插值函數代碼分析學習,用的CImage類load圖像。
// Imagejoint.cpp : 定義控制台應用程序的入口點。 // #include "stdafx.h" #include "Imagejoint.h" #include "math.h" #include <afxwin.h> #ifdef _DEBUG #define new DEBUG_NEW #endif #include <atlimage.h>//CImage類 #include <locale.h> // The one and only application object CWinApp theApp; using namespace std; //雙三次插值系數 double fs(double w) { double a=-0.5; double fs; if (abs(w)<=1) fs=(a+2)*pow(abs(w),3)-(a+3)*pow(abs(w),2)+1; else if (abs(w)>1&&abs(w)<=2) fs=a*pow(abs(w),3)-5*a*pow(abs(w),2)+8*a*abs(w)-4*a; else fs=0; return fs; } HRESULT Imagejoint(PBYTE pbSrc,int iWidth,int iHeight,double dbRotate,double dbZoom,PBYTE pbTag); int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0;//表示整數類型的函數返回碼。n表示整數類型,Ret是Return的縮寫,表示返回值,Code表示代碼。 setlocale(LC_ALL,"chs"); HMODULE hModule = ::GetModuleHandle(NULL); if (hModule != NULL) { // initialize MFC and print and error on failure CImage cImage; HRESULT hResult; //初始化一些變量 int iWidth,iHeight,iBytePerPixel,iPitch; int x,y; PBYTE pbSrc=NULL,pbTag=NULL;//源圖、目標圖 PBYTE pbImage=NULL;//load圖像后存在這 PDWORD pdwImage=NULL;//用於保存圖像 double dbRotate=0,dbZoom=0; do{ if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0)) { // TODO: change error code to suit your needs _tprintf(_T("Fatal Error: MFC initialization failed\n")); nRetCode = 1; break; } // TODO: code your application's behavior here. if(argc<5) { _tprintf(_T("使用方法:Imagejoint 源圖像文件 旋轉角度 縮放倍數 輸出文件\n")); nRetCode= -1; break; } _stscanf(argv[2],_T("%lf"),&dbRotate); _stscanf(argv[3],_T("%lf"),&dbZoom); if(!((dbRotate>=0 && dbRotate<360) && (dbZoom>=0.25 && dbZoom<=16))) { _tprintf(_T("“旋轉角度” 或 “縮放倍數”參數錯誤!\n")); nRetCode= -2; break; } //Load 圖像到cImage對象中 hResult=cImage.Load(argv[1]); if(hResult!=ERROR_SUCCESS) { _tprintf(_T("源圖像文件名錯誤!\n")); nRetCode= -3; break; } iWidth=cImage.GetWidth(); iHeight=cImage.GetHeight(); //分配源圖內存 pbSrc = (PBYTE)malloc(iWidth*iHeight); //分配目標圖內存 if(dbZoom>1) pbTag = (PBYTE)malloc(ceil(iWidth*dbZoom)*ceil(iHeight*dbZoom)); else pbTag = (PBYTE)malloc(iWidth*iHeight); if(pbSrc==NULL || pbTag==NULL ) { _tprintf(_T("內存申請錯誤!\n")); nRetCode= -4; break; } //cImage數據存到pbImage,后再轉換為源灰度圖pbSrc iPitch=cImage.GetPitch(); iBytePerPixel=(cImage.GetBPP()+7)/8; if(iBytePerPixel==3) { for(y=0;y<iHeight;y++) { //load的圖像數據放到pbImage pbImage=(PBYTE)(PBYTE(cImage.GetBits())+iPitch*y);//得到的是圖像初始像素地址 for(x=0;x<iWidth;x++) { //pbImage轉換為灰度圖pbSrc pbSrc[y*iWidth+x]=(pbImage[3*x]*0.15+pbImage[3*x+1]*0.55+pbImage[3*x+2]*0.3); } } } cImage.Destroy(); //TO DO:執行操作 hResult=Imagejoint(pbSrc,iWidth,iHeight,dbRotate,dbZoom,pbTag); if(hResult!=ERROR_SUCCESS) { _tprintf(_T("圖像處理錯誤!\n")); nRetCode= -5; break; } //處理后保存圖像 iWidth=ceil(iWidth*dbZoom); iHeight=ceil(iHeight*dbZoom); cImage.Create(iWidth,-iHeight,32); iPitch=cImage.GetPitch(); for(y=0;y<iHeight;y++) { pdwImage=(PDWORD)(PBYTE(cImage.GetBits())+iPitch*y); for(x=0;x<iWidth;x++) { pdwImage[x]=pbTag[y*iWidth+x]*0x10101; } } //待保存圖像文件名 CString csTagName=argv[4]; csTagName.Trim(); csTagName.MakeUpper(); if(csTagName.Right(4)!=_T(".BMP") ) csTagName.Append(_T(".BMP")); hResult=cImage.Save(csTagName); if(hResult!=ERROR_SUCCESS) { _tprintf(_T("圖像結果保存錯誤!\n")); nRetCode= -5; break; } _tprintf(_T("圖像處理成功!\n")); nRetCode= ERROR_SUCCESS; break; }while(0); if(pbSrc) free(pbSrc); if(pbTag) free(pbTag); } else { // 可以根據需求更改錯誤提示 _tprintf(_T("Fatal Error: GetModuleHandle failed\n")); nRetCode = 1; } getchar(); return nRetCode; } HRESULT Imagejoint(PBYTE pbSrc,int iWidth,int iHeight,double dbRotate,double dbZoom,PBYTE pbTag) { int size; if(dbZoom>1) { size=iWidth*iHeight; } else { size=ceil(iWidth*dbZoom)*ceil(iHeight*dbZoom); } //旋轉中心為圖像中心 double rx0=iWidth; double ry0=iHeight; double srcx,srcy,u,v; int xOr,yOr; //int zoom=ceil(dbZoom); dbRotate=dbRotate*3.1415926/180.0; for (int y=0;y<dbZoom*iHeight;y++) { for (int x=0;x<dbZoom*iWidth;x++) { srcx=(double)((x-rx0)*cos(dbRotate) - (y-ry0)*sin(dbRotate) + rx0) ; srcy=(double)((x-rx0)*sin(dbRotate) + (y-ry0)*cos(dbRotate) + ry0) ; srcx=srcx*1/dbZoom; srcy=srcy*1/dbZoom; xOr = floor(srcx); yOr = floor(srcy); u=srcx-xOr; v=srcy-yOr; if( !(srcx>=0 && srcx<=iWidth && srcy>=0 && srcy<=iHeight)) { pbTag[y*2*iWidth+x]=0;//255 } else { double middle= pbSrc[(yOr-1)*iWidth+(xOr-1)]*fs(1+u)*fs(1+v)+ pbSrc[(yOr)*iWidth+(xOr-1)]*fs(1+u)*fs(v)+ pbSrc[(yOr+1)*iWidth+(xOr-1)]*fs(1+u)*fs(1-v)+ pbSrc[(yOr+2)*iWidth+(xOr-1)]*fs(1+u)*fs(2-v)+ pbSrc[(yOr-1)*iWidth+(xOr)]*fs(u)*fs(1+v)+ pbSrc[(yOr)*iWidth+(xOr)]*fs(u)*fs(v)+ pbSrc[(yOr+1)*iWidth+(xOr)]*fs(u)*fs(1-v)+ pbSrc[(yOr+2)*iWidth+(xOr)]*fs(u)*fs(2-v)+ pbSrc[(yOr-1)*iWidth+(xOr+1)]*fs(1-u)*fs(1+v)+ pbSrc[(yOr)*iWidth+(xOr+1)]*fs(1-u)*fs(v)+ pbSrc[(yOr+1)*iWidth+(xOr+1)]*fs(1-u)*fs(1-v)+ pbSrc[(yOr+2)*iWidth+(xOr+1)]*fs(1-u)*fs(2-v)+ pbSrc[(yOr-1)*iWidth+(xOr+2)]*fs(2-u)*fs(1+v)+ pbSrc[(yOr)*iWidth+(xOr+2)]*fs(2-u)*fs(v)+ pbSrc[(yOr+1)*iWidth+(xOr+2)]*fs(2-u)*fs(1-v)+ pbSrc[(yOr+2)*iWidth+(xOr+2)]*fs(2-u)*fs(2-v); if(middle<=255&&middle>=0) pbTag[y*2*iWidth+x]=middle; else if(middle>255) pbTag[y*2*iWidth+x]=255; else pbTag[y*2*iWidth+x]=0; } } } //memcpy(pbTag,pbSrc,size); return ERROR_SUCCESS; }