📄 rotation.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 + -