⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rotation.c

📁 图像旋转
💻 C
字号:
#include <stdio.h> 
double fsin(double a)
{
    double result,x,n;
    int i,j,k,l,m;
    result=a;
    for(i=1;i<=80;i++)
	 {   n=1;
	     m=1;
	     x=1.0;
	     for(j=1;j<=i;j++)
	     m=-m;
	     for(k=1;k<=(2*i+1);k++)
	     x=x*a;
	     for(l=1;l<=(2*i+1);l++)
	     n=n*l;
	     result=result+(m*(x/n));
	 }
	 return result;
}
double fcos(double a)
{
    double result,x,n;
    int i,j,k,l,m;
    result=1;
    for(i=1;i<=80;i++)
	 {   n=1;
	     m=1; 
	     x=1.0;
	     for(j=1;j<=i;j++)
	     m=-m;
	     for(k=1;k<=(2*i);k++)
	     x=x*a;
	     for(l=1;l<=(2*i);l++)
	     n=n*l;
	     result=result+(m*(x/n));
	 }
return result;
}
double fabs(double a)
{
	if(a>=0) return a;
	else return -a;
}
// get the offset value of image from 
static unsigned int readimageoffset(FILE *srcfptr)
{
	unsigned char readBuffer[4];

	unsigned char a0, a1, a2,a3;

	fpos_t filePos;
	filePos  = 10;

	//set read pointer position
	fsetpos(srcfptr,&filePos);
	// read the value of offset
	fread(readBuffer,4,1,srcfptr);
	a0 = readBuffer[0];
	a1 = readBuffer[1];
	a2 = readBuffer[2];
	a3 = readBuffer[3];

	return ((((((a3 << 8) | a2) << 8) |a1) << 8) | a0);
}
static unsigned int readimagebi(FILE *srcfptr)
{
	unsigned char readBuffer[2];

	unsigned char a0, a1;

	fpos_t filePos;
	filePos  = 28;

	//set read pointer position
	fsetpos(srcfptr,&filePos);
	// read the value of offset
	fread(readBuffer,2,1,srcfptr);
	a0 = readBuffer[0];
	a1 = readBuffer[1];
	return ((a1 << 8) | a0);
}
void rotation(FILE *srcaddr, FILE *dstaddr,long width,long height,int angle) 
{ 
    int base=readimageoffset(srcaddr); //源文件像素起点
    int imagebi=readimagebi(srcaddr);  //每个像素的位数
	int a=imagebi/8;
	long i,j,k,l;    /*循环变量:像素在新DIB中的坐标*/	
	long i0,j0;   /*循环变量:像素在旧DIB中的坐标*/
	long newwidth,newheight;  //新图像宽度及高度
	long rotawidth;
	long  biline=((width*imagebi+31)/32)*4;	 /*计算旧图每行的字节数*/
	long newbili;  /*新图像每行的字节数*/
	long imagescr;  //新图像像素的字节数
	long filescr;   //新文件大小
	double fangle;  /*旋转弧度*/
	double sinf,cosf;
	double f1,f2;
	double srcx1,srcy1,srcx2,srcy2,srcx3,srcy3,srcx4,srcy4;
	double dstx1,dsty1,dstx2,dsty2,dstx3,dsty3,dstx4,dsty4;
	unsigned char c[5];
	unsigned char readbuff[height][biline];
	
	fpos_t filepos=0;
	
	/*旋转弧度的正弦和余弦*/
	fangle=((double)angle/180)*3.1415;	
	sinf=fsin(fangle);		
	cosf=fcos(fangle);
	/*以图像中心为原点计算源图四个角的坐标*/
	srcx1=(-((float)(width-1))/2);
	srcy1=(((float)(height-1))/2);
	srcx2=(((float)(width-1))/2);
	srcy2=(((float)(height-1))/2);
	srcx3=((-(float)(width-1))/2);
	srcy3=((-(float)(height-1))/2);
	srcx4=(((float)(width-1))/2);
	srcy4=(-((float)(height-1))/2);
	
	/*以图像中心为原点计算新图四个角的坐标*/
	dstx1=cosf*srcx1+sinf*srcy1;
	dsty1=-sinf*srcx1+cosf*srcy1;
	dstx2=cosf*srcx2+sinf*srcy2;
	dsty2=-sinf*srcx2+cosf*srcy2;
	dstx3=cosf*srcx3+sinf*srcy3;
	dsty3=-sinf*srcx3+cosf*srcy3;
	dstx4=cosf*srcx4+sinf*srcy4;
	dsty4=-sinf*srcx4+cosf*srcy4;
	
	/*计算新图像的宽和高*/
	if(fabs(dstx4-dstx1)>=fabs(dstx3-dstx2)) rotawidth=(long)(fabs(dstx4-dstx1)+0.5);
	else rotawidth=(long)(fabs(dstx3-dstx2)+0.5);
	newwidth=((rotawidth*8+31)/32)*4;
	if(fabs(dsty4-dsty1)>=fabs(dsty3-dsty2)) newheight=(long)(fabs(dsty4-dsty1)+0.5);
	else newheight=(long)(fabs(dsty3-dsty2)+0.5);
   
	newbili=newwidth*a; /*计算新图每行的字节数*/
	imagescr=newbili*newheight;
	filescr=imagescr+base;
	//复制文件头
	fsetpos(srcaddr,&filepos);
	fsetpos(dstaddr,&filepos);
	for(i=0;i<base;i++)
	{
		fread(c,1,1,srcaddr);
		fwrite(c,1,1,dstaddr);
	}
	//将像素读到缓冲区
	for(i=0;i<height;i++)
		for(j=0;j<biline;j++)
			fread(&readbuff[i][j],1,1,srcaddr);
		
	f1=(double)(-0.5*(rotawidth-1)*cosf-0.5*(newheight-1)*sinf+0.5*(width-1));
	f2=(double)(0.5*(rotawidth-1)*sinf-0.5*(newheight-1)*cosf+0.5*(height-1));
	
	filepos=base;
	fsetpos(dstaddr,&filepos);
    for(i=0;i<newheight;i++)  /*针对像素每行进行操作*/
	{
		for(j=0;j<newwidth;j++)  /*针对像素每列进行操作*/
		{
			/*计算该像素在源DIB中的坐标*/
			i0=(long)(-((double)j)*sinf+((double)i)*cosf+f2+0.5);			
			j0=(long)(((double)j)*cosf+((double)i)*sinf+f1+0.5);			
			/*判断是否在源图范围内*/
			if((j0>=0)&&(j0<width)&&(i0>=0)&&(i0<height))
			{
			   k=j0*a; 
			   fwrite(&readbuff[i0][k],a,1,dstaddr);
			}
			else
			{ 
				/*对不在源图内的像素操作*/				
				for(l=0;l<a;l++)  c[l]=(char)255;
				fwrite(c,a,1,dstaddr);				
			}
		}
	}    
    c[0]=(unsigned char)filescr;
    c[1]=(unsigned char)(filescr>>8);
	c[2]=(unsigned char)(filescr>>16);
	c[3]=(unsigned char)(filescr>>24);
	filepos=2;
	fsetpos(dstaddr,&filepos);
	fwrite(c,4,1,dstaddr);
	c[0]=(unsigned char)newwidth;
    c[1]=(unsigned char)(newwidth>>8);
	c[2]=(unsigned char)(newwidth>>16);
	c[3]=(unsigned char)(newwidth>>24);
	filepos=18;
	fsetpos(dstaddr,&filepos);
	fwrite(c,4,1,dstaddr);
	c[0]=(unsigned char)newheight;
    c[1]=(unsigned char)(newheight>>8);
	c[2]=(unsigned char)(newheight>>16);
	c[3]=(unsigned char)(newheight>>24);
	fwrite(c,4,1,dstaddr);
	c[0]=(unsigned char)imagescr;
    c[1]=(unsigned char)(imagescr>>8);
	c[2]=(unsigned char)(imagescr>>16);
	c[3]=(unsigned char)(imagescr>>24);
	filepos=34;
	fsetpos(dstaddr,&filepos);
	fwrite(c,4,1,dstaddr);
}
int main()
{  
	FILE *srcaddr;
	FILE *dstaddr;
	long width=800;
	long height=600;
	int angle=45;
	srcaddr=fopen("d:\\DIP\\internet.bmp","rb");
	dstaddr=fopen("d:\\DIP\\rotinternet1.bmp","wb+");
	rotation(srcaddr,dstaddr,width,height,angle);
    fclose(dstaddr);
    fclose(srcaddr);	
	return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -