基於C++影像處理-任意角度的高品質的快速的映像旋轉

來源:互聯網
上載者:User

在CSDN的BLOG中,看到這篇文章

http://blog.csdn.net/housisong/archive/2007/04/27/1586717.aspx

 

裡面用C++實現的,現在我用C++複現了一下,希望以後用Python再實現。

 

假設對圖片上任意點 (x,y) ,繞一個座標點 (rx0,ry0) 逆時針旋轉 a 角度後的新的座標設為 (x', y') ,有公式:

 

先貼幾個檔案

 

imgtool.h

 

#define PI 3.141592;<br />#include <math.h><br />#include <stdio.h><br />#include <stdlib.h><br />#include <iostream></p><p>struct TPicRegion<br />{<br /> unsigned char* pdata;<br /> long byte_width;<br /> long width;<br /> long height;<br />};</p><p>#pragma pack( push, 2 )</p><p>struct bmpfileheader<br />{<br />unsigned short type;<br />unsigned int size;<br />unsigned short resa;<br />unsigned short resb;<br />unsigned int offset;<br />};<br />#pragma pack( pop )</p><p>struct bmpinfoheader<br />{<br />unsigned int size;<br />long width;<br />long height;<br />unsigned short plane;<br />unsigned short bitcount;<br />unsigned int compress;<br />unsigned int imgsize;<br />long xdpm;<br />long ydpm;<br />unsigned int colornum;<br />unsigned int colorimp;<br />};</p><p>void PicRotary2(TPicRegion* Dst,TPicRegion* Src,int Angle,double ZoomX,double ZoomY,double move_x,double move_y);<br />void PicRotary3(TPicRegion* Dst,TPicRegion* Src,int Angle);<br />int ImgOperate(int ActionFlag,int angle,int *CropCoorL,int *CropCoorR,char *OpenImage,char *NewIamge,double ZoomX,double ZoomY,double move_x,double move_y);<br />void PicCrop(TPicRegion* Dst,TPicRegion* Src,int *CropCoorL,int *CropCoorR);<br />void usage(void);<br />int String2Int(char *Sce,int Len,int *Result);

main.cpp

#include "imgtool.h"</p><p>int String2Float(char *Sce,int Len,double *Result)<br />{<br />int j=0;<br />int Countflag=0;<br />int Countindex=0;<br />int DecimalFlage=1;<br />j=0;<br />while(j<Len)<br />{<br />if(Sce[j]<58&&Sce[j]>46)<br />{<br />if(Countflag==0)<br />{<br />Result[Countindex]=double(Sce[j]-48);<br />Countflag=1;<br />}<br />else if(Countflag==1)<br />{Result[Countindex]=Result[Countindex]*10+(Sce[j]-48);<br />}<br />else if(Countflag==2)<br />{<br />Result[Countindex]=Result[Countindex]+pow(0.1,DecimalFlage)*(Sce[j]-48);<br />DecimalFlage++;<br />}</p><p>}<br />else if(Sce[j]==',')<br />{<br />Countindex++;<br />Countflag=0;<br />DecimalFlage=1;<br />}<br />else if(Sce[j]=='.')<br />{<br />Countflag=2;<br />}</p><p>j++;<br />}<br />return Countindex+1;<br />}</p><p>int main(int argc, char *argv[])<br />{<br /> int i=1,j;<br />int ActionFlag=0;<br />int angle=0;<br />char *OpenImage,*NewIamge;<br />int CropCoorL[2]={0,0};<br />int CropCoorR[2]={0,0};<br />double Zoom[2]={1.0,1.0};<br />int Move[2]={0,0};<br />bool NewImageFlage=false;<br />bool OpenImageFlage=false;<br />while(i<argc)<br />{<br />if(strcmp(argv[i],"-o")== 0)<br />OpenImageFlage=true;<br />if(strcmp(argv[i],"-s")== 0)<br />NewImageFlage=true;<br />if(strcmp(argv[i],"-c")== 0)<br />ActionFlag++;<br />if( strcmp(argv[i],"-r")==0)<br />ActionFlag++;<br />i++;<br />}<br />if(ActionFlag==2)<br />{<br />printf("Warning:invalid input!/n");<br />printf("only one choice: Crop or Rotate!");<br />usage();<br />return -1;<br />}<br />if(ActionFlag==0)<br />{<br />printf("Warning:invalid input!/n");<br />printf("one action must be choosed : Crop or Rotate!");<br />usage();<br />return -1;<br />}<br />if(NewImageFlage==false)<br />{<br />printf("Warning:invalid input!/n");<br />printf("need a new image name to save!");<br />usage();<br />return -1;<br />}<br />if(OpenImageFlage==false)<br />{<br />printf("Warning:invalid input!/n");<br />printf("need a exiting image name to open!");<br />usage();<br />return -1;<br />}<br />ActionFlag=0;<br />i=1;<br />while(i<argc)<br />{<br />if( strcmp(argv[i],"-r")==0)<br />{<br />i++;<br />ActionFlag=1;<br />printf("going to rotary!/n");<br />angle=atoi(argv[i]);<br />printf("angle is %d/n",angle);<br />}<br />if(strcmp(argv[i],"-c")== 0)<br />{<br />ActionFlag=2;<br />printf("going to crop!/n");<br />i++;<br />String2Int(argv[i],strlen(argv[i]),CropCoorL);<br />i++;<br />String2Int(argv[i],strlen(argv[i]),CropCoorR);<br />printf("coordinate is /n");<br />for(j=0;j<2;j++)<br />{<br />printf(" %d",CropCoorL[j]);<br />}<br />for(j=0;j<2;j++)<br />{<br />printf(" %d",CropCoorR[j]);<br />}<br />printf("/n");<br />if(CropCoorL[0]>CropCoorR[0]||CropCoorL[1]>CropCoorR[1])<br />{<br />printf("Warning:invalid input!/n");<br />printf("please input correct coordinate to crop!/n");<br />usage();<br />return -1;<br />}<br />}<br />if( strcmp(argv[i],"-s")==0)<br />{<br />i++;<br />NewIamge=argv[i];<br />printf("New Image Name : %s/n",NewIamge);<br />}<br />if( strcmp(argv[i],"-o")==0)<br />{<br />i++;<br />OpenImage=argv[i];<br />printf("Exiting Image Name: %s/n",OpenImage);<br />}<br />if( strcmp(argv[i],"-z")==0)<br />{<br />i++;<br />String2Float(argv[i],strlen(argv[i]),Zoom);<br />printf("ZoomX=%f,ZoomY=%f/n",Zoom[0],Zoom[1]);<br />}<br />if( strcmp(argv[i],"-m")==0)<br />{<br />i++;<br />String2Int(argv[i],strlen(argv[i]),Move);<br />printf("MoveX=%d,MoveY=%d/n",Move[0],Move[1]);<br />}<br />i++;<br />}<br />ImgOperate(ActionFlag,angle,CropCoorL,CropCoorR,OpenImage,NewIamge,Zoom[0],Zoom[1],Move[0],Move[1]);<br />return 0;<br />}

 

imgtool.cpp

#include "imgtool.h"</p><p>void PicRotary2(TPicRegion* Dst,TPicRegion* Src,int Angle,double ZoomX,double ZoomY,double move_x,double move_y)<br />{<br />double RotaryAngle=Angle*PI;<br />RotaryAngle=RotaryAngle/180.0;<br /> double Dstrx=Dst->width*0.5;<br /> double Dstry=Dst->height*0.5;<br /> double Srcrx=Src->width*0.5;<br /> double Srcry=Src->height*0.5;<br />double sinA=sin(RotaryAngle);<br />double cosA=cos(RotaryAngle);</p><p> for (long y=0;y<Dst->height;++y)<br /> {<br /> for (long x=0;x<Dst->width;++x)<br /> {<br /> long srcx=(long)((x-Dstrx-move_x)/ZoomX*cosA - (y-Dstry-move_y)/ZoomY*sinA + Srcrx) ;<br /> long srcy=(long)((x-Dstrx-move_x)/ZoomX*sinA + (y-Dstry-move_y)/ZoomY*cosA + Srcry) ;<br />if ((srcx>=0)&&(srcx<Src->width) && (srcy>=0)&&(srcy<Src->height))<br />{<br />memcpy(Dst->pdata+Dst->byte_width*y+3*x,Src->pdata+Src->byte_width*srcy+3*srcx,3);<br />}<br />else<br />{<br />Dst->pdata[Dst->byte_width*y+3*x]=0x00;<br />Dst->pdata[Dst->byte_width*y+3*x+1]=0x00;<br />Dst->pdata[Dst->byte_width*y+3*x+2]=0x00;<br />}<br /> }<br /> }</p><p>}<br />void PicCrop(TPicRegion* Dst,TPicRegion* Src,int *CropCoorL,int *CropCoorR)<br />{<br />int i=0;<br />int j=0;<br />int temp=CropCoorL[1];<br />CropCoorL[1]=Src->height-CropCoorR[1];<br />CropCoorR[1]=Src->height-temp;<br />for (long y=CropCoorL[1];y<=CropCoorR[1];++y)<br /> {<br /> i=0;<br />for (long x=CropCoorL[0];x<=CropCoorR[0];++x)<br /> {<br />memcpy(Dst->pdata+Dst->byte_width*j+3*i,Src->pdata+Src->byte_width*y+3*x,3);<br />i++;<br />}<br />j++;<br />}<br />}<br />void usage(void)<br />{<br />printf("/nUsage: imgtool /n");<br />printf(" [-o ExitImageName] Open the exiting image/n");<br />printf(" [-r angle | -c x1,y1 x2,y2] Rotate some angles or Crop from top left corner to right down corner/n");<br />printf(" [-s NewImageName] Save the result by a new image name/n");<br />printf(" [-z ZoomX,ZoomY] Zoom in the x and y vector/n");<br />printf(" [-m MoveX,MoveY] Move in the x and y vector/n");<br />}<br />int String2Int(char *Sce,int Len,int *Result)<br />{<br />int j=0;<br />int Countflag=0;<br />int Countindex=0;<br />j=0;<br />while(j<Len)<br />{<br />if(Sce[j]<58&&Sce[j]>46)<br />{<br />if(Countflag==0)<br />{<br />Result[Countindex]=Sce[j]-48;<br />Countflag=1;<br />}<br />else<br />{Result[Countindex]=Result[Countindex]*10+Sce[j]-48;<br />}<br />}<br />else if(Sce[j]==',')<br />{<br />Countindex++;<br />Countflag=0;<br />}<br />j++;<br />}<br />return Countindex+1;<br />}

imgoperate.cpp

 

 #include "imgtool.h"</p><p>int ImgOperate(int ActionFlag,int angle,int *CropCoorL,int *CropCoorR,char *OpenImage,char *NewIamge,double ZoomX,double ZoomY,double move_x,double move_y)<br />{<br />int nread = 0;<br />FILE *NewFp;<br />FILE *SrcFp = fopen( OpenImage, "rb" );<br />if( NULL == SrcFp )<br />{<br />printf( "Bitmap file %s not found./n", OpenImage );<br />return -1;<br />}<br />bmpfileheader Srcbfh;<br />nread = fread( &Srcbfh, sizeof(Srcbfh), 1, SrcFp );</p><p>if( Srcbfh.type != 0x4d42 )<br />{<br />printf( "File %s is not a bitmap file./n", OpenImage );<br />return -2;<br />}<br />bmpinfoheader Srcbih;<br />nread = fread( &Srcbih, sizeof(Srcbih), 1, SrcFp );</p><p>nread = fseek( SrcFp, Srcbfh.offset, SEEK_SET );<br />if( nread )<br />{<br />printf( "Data Seek error./n" );<br />return -3;<br />}<br />int Srcbytespl = ((Srcbih.width*Srcbih.bitcount+31)>>5)<<2;<br />unsigned char* SrcImgdata = new unsigned char[Srcbytespl*Srcbih.height];<br />nread = fread( SrcImgdata, Srcbytespl, Srcbih.height, SrcFp );<br />fclose( SrcFp );</p><p>TPicRegion Dst;<br />TPicRegion Src;<br />Src.byte_width=Srcbytespl;<br />Src.height=Srcbih.height;<br />Src.width=Srcbih.width;<br />Src.pdata=SrcImgdata;<br />long SrcMaxLen;<br />if(ActionFlag==1)<br />{<br />printf("going to rotate!/n");<br />if(Srcbih.height>Srcbih.width)<br />SrcMaxLen=Srcbih.height;<br />else<br />SrcMaxLen=Srcbih.width;<br />Dst.height=long((double)SrcMaxLen*1.414+(double)0.999);<br />Dst.byte_width=((Dst.height*Srcbih.bitcount+31)>>5)<<2;<br />unsigned char* DstImgdata = new unsigned char[Dst.byte_width*Dst.height];<br />Dst.width = Dst.height;<br />Dst.pdata=DstImgdata;<br />PicRotary2(&Dst,&Src,angle,ZoomX,ZoomY,move_x,move_y);<br />bmpfileheader Dstbfh;<br />Dstbfh=Srcbfh;<br />bmpinfoheader Dstbih;<br />Dstbih=Srcbih;<br />Dstbfh.size=Srcbfh.offset+Dst.byte_width*Dst.height;<br />Dstbih.height=Dst.height;<br />Dstbih.width=Dst.width;<br />NewFp=fopen(NewIamge,"wb+");<br />fwrite(&Dstbfh,sizeof(Dstbfh),1,NewFp);<br />fclose(NewFp);<br />NewFp=fopen(NewIamge,"ab");<br />fwrite(&Dstbih,sizeof(Dstbih),1,NewFp);<br />fwrite(Dst.pdata,sizeof(unsigned char),Dst.byte_width*Dst.height,NewFp);<br />fclose(NewFp);<br />}<br />else if(ActionFlag==2)<br />{<br />printf("going to crop!/n");<br />Dst.height=CropCoorR[1]-CropCoorL[1]+1;<br />Dst.width =CropCoorR[0]-CropCoorL[0]+1;<br />Dst.byte_width=((Dst.width*Srcbih.bitcount+31)>>5)<<2;<br />unsigned char* DstImgdata = new unsigned char[Dst.byte_width*Dst.height];<br />Dst.pdata=DstImgdata;<br />PicCrop(&Dst,&Src,CropCoorL,CropCoorR);<br />bmpfileheader Dstbfh;<br />Dstbfh=Srcbfh;<br />bmpinfoheader Dstbih;<br />Dstbih=Srcbih;<br />Dstbfh.size=Srcbfh.offset+Dst.byte_width*Dst.height;<br />Dstbih.height=Dst.height;<br />Dstbih.width=Dst.width;<br />NewFp=fopen(NewIamge,"wb+");<br />fwrite(&Dstbfh,sizeof(Dstbfh),1,NewFp);<br />fclose(NewFp);<br />NewFp=fopen(NewIamge,"ab");<br />fwrite(&Dstbih,sizeof(Dstbih),1,NewFp);<br />fwrite(Dst.pdata,sizeof(unsigned char),Dst.byte_width*Dst.height,NewFp);<br />fclose(NewFp);<br />}<br />return 0;<br />}

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.