C++影象縮放
轉自:http://blog.csdn.net/welcome_xu/article/details/7251316
VC++中自帶的影象縮放函式兩個:
1、
BOOL StretchBlt ( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop );
2、
int StretchDIBits( HDC hdc, // handle to DC int XDest, // x-coord of destination upper-left corner int YDest, // y-coord of destination upper-left corner int nDestWidth, // width of destination rectangle int nDestHeight, // height of destination rectangle int XSrc, // x-coord of source upper-left corner int YSrc, // y-coord of source upper-left corner int nSrcWidth, // width of source rectangle int nSrcHeight, // height of source rectangle CONST VOID *lpBits, // bitmap bits CONST BITMAPINFO *lpBitsInfo, // bitmap data UINT iUsage, // usage options DWORD dwRop // raster operation code );
這兩個函式的作用是將影象的一部分或全部複製到另一個框架裡面去,如果新框架比原來的部分大,則將影象進行放大,否則縮小。(聽說這兩個函式縮放效果不好,容易引起影象失真)
自己編寫影象縮放程式碼:
int NewWidth=int(Width*fx+0.5);
int NewHeight=int(Height*fy+0.5);
int NewLineBytes=WIDTHBYTES(NewWidth*8);
HDIB hNewDIB=(HDIB)::GlobalAlloc(GHND,40+4*256+NewLineBytes*NewHeight);//分配控制程式碼空間
if(hNewDIB==NULL) return;
LPBYTE lpDIBnew=(LPBYTE)::GlobalLock((HGLOBAL)hNewDIB);//由新控制程式碼得到第二部分指標
memcpy(lpDIBnew,lpDIB,1064);//複製資訊頭和調色盤
BYTE* lpDIBBitsnew=(BYTE*)(lpDIBnew+40+4*256);//得到第四部分指標
int i0,j0;//影象在原DIB中的座標
int i,j;//影象在新DIB中的座標
float m,n;
for(i=0;i<NewHeight;i++)//雙線性插值
for(j=0;j<NewWidth;j++)
{
i0=(int)(i/fy+0.5);j0=(int)(j/fx+0.5);//計算該象素在原DIB中的座標
if((j0>=0)&&(j0<Width)&&(i0>=0)&&(i0<Height))//判斷是否在原影象範圍內
int NewHeight=int(Height*fy+0.5);
int NewLineBytes=WIDTHBYTES(NewWidth*8);
HDIB hNewDIB=(HDIB)::GlobalAlloc(GHND,40+4*256+NewLineBytes*NewHeight);//分配控制程式碼空間
if(hNewDIB==NULL) return;
LPBYTE lpDIBnew=(LPBYTE)::GlobalLock((HGLOBAL)hNewDIB);//由新控制程式碼得到第二部分指標
memcpy(lpDIBnew,lpDIB,1064);//複製資訊頭和調色盤
BYTE* lpDIBBitsnew=(BYTE*)(lpDIBnew+40+4*256);//得到第四部分指標
int i0,j0;//影象在原DIB中的座標
int i,j;//影象在新DIB中的座標
float m,n;
for(i=0;i<NewHeight;i++)//雙線性插值
for(j=0;j<NewWidth;j++)
{
i0=(int)(i/fy+0.5);j0=(int)(j/fx+0.5);//計算該象素在原DIB中的座標
if((j0>=0)&&(j0<Width)&&(i0>=0)&&(i0<Height))//判斷是否在原影象範圍內
{
m=(float)(i/fy+0.5)-i0;n=(float)(j/fx+0.5)-(int)j0;
BYTE x1,x2,y1,y2;
x1=*(lpDIBBits+int(LineBytes*(Height-i0-1)+j0));
x2=*(lpDIBBits+int(LineBytes*(Height-i0-1)+j0+1));
y1=*(lpDIBBits+int(LineBytes*(Height-i0)+j0));
y2=*(lpDIBBits+int(LineBytes*(Height-i0)+j0+1));
*(lpDIBBitsnew+NewLineBytes*(NewHeight-i-1)+j)=(BYTE)((1-m)*(1-n)*x1+(1-m)*n*x2+m*(1-n)*y1+m*n*y2);
m=(float)(i/fy+0.5)-i0;n=(float)(j/fx+0.5)-(int)j0;
BYTE x1,x2,y1,y2;
x1=*(lpDIBBits+int(LineBytes*(Height-i0-1)+j0));
x2=*(lpDIBBits+int(LineBytes*(Height-i0-1)+j0+1));
y1=*(lpDIBBits+int(LineBytes*(Height-i0)+j0));
y2=*(lpDIBBits+int(LineBytes*(Height-i0)+j0+1));
*(lpDIBBitsnew+NewLineBytes*(NewHeight-i-1)+j)=(BYTE)((1-m)*(1-n)*x1+(1-m)*n*x2+m*(1-n)*y1+m*n*y2);
}
else
*((unsigned char*)(lpDIBBitsnew+NewLineBytes*i+j))=255;//對於原影象中沒有的畫素,直接賦值為255
}
LPBITMAPINFOHEADER h=(LPBITMAPINFOHEADER)lpDIBnew;//獲得指向新影象資訊頭的指標
h->biHeight=NewHeight;//更新資訊頭的資訊
h->biWidth=NewWidth;
h->biSizeImage=NewWidth*NewHeight;
pDoc->hDib=hNewDIB;
pDoc->dWidth=NewWidth;pDoc->dHeight=NewHeight;
OnInitialUpdate();
Invalidate(TRUE);
delete dlg;
else
*((unsigned char*)(lpDIBBitsnew+NewLineBytes*i+j))=255;//對於原影象中沒有的畫素,直接賦值為255
}
LPBITMAPINFOHEADER h=(LPBITMAPINFOHEADER)lpDIBnew;//獲得指向新影象資訊頭的指標
h->biHeight=NewHeight;//更新資訊頭的資訊
h->biWidth=NewWidth;
h->biSizeImage=NewWidth*NewHeight;
pDoc->hDib=hNewDIB;
pDoc->dWidth=NewWidth;pDoc->dHeight=NewHeight;
OnInitialUpdate();
Invalidate(TRUE);
delete dlg;
裡面用到的是雙線性內插法。(比最鄰近法好,減少失真)
相關文章
- OpenCV(iOS)影象尺寸縮放(14)OpenCViOS
- [Python影象處理] 六.影象縮放、影象旋轉、影象翻轉與影象平移Python
- 影象縮放--插值法(opencv,原理)OpenCV
- 使用StretchBlt函式進行影象縮放函式
- 【影象演算法】高斯模糊+徑向縮放模糊演算法
- [work] 影象縮放——雙線性插值演算法演算法
- C#影象顯示實現拖拽、錨點縮放功能【轉】C#
- 【數字影象處理】六.MFC空間幾何變換之影象平移、映象、旋轉、縮放詳解
- 影象縮放的雙線性內插值演算法的原理解析演算法
- 縮放比
- JPEG影象的解壓縮操作
- C++影象處理 -- 影象黑白調整應用C++
- 如何縮放SVGSVG
- UWPWebView禁用縮放WebView
- 圖形影象處理-之-高質量的快速的影象縮放 上篇 近鄰取樣插值和其速度優化優化
- Android平臺影象壓縮方案Android
- 【開源】canvas影象裁剪、壓縮、旋轉Canvas
- cad縮放快捷鍵命令 cad縮放快捷鍵使用的方法
- 圖形影象處理-之-高質量的快速的影象縮放 中篇 二次線性插值和三次卷積插值卷積
- Android 圖片縮放Android
- 實現圖片縮放
- android 拖拽與縮放Android
- 淺析Android平臺影象壓縮方案Android
- 深度學習影象視訊壓縮技術深度學習
- win10游標怎麼縮放_win10游標縮放方法Win10
- CAD如何使用縮放命令
- html 圖片按比例縮放HTML
- 縮放控制ZoomControlsOOM
- Java中縮放緩衝影像Java
- 第二屆學習影象壓縮挑戰賽
- 一文讀懂影象壓縮演算法演算法
- 網路攝像機—影象壓縮方式—JPEG、MJPEG
- 自己寫遠端控制軟體之影象壓縮
- win10怎麼開啟自定義縮放 win10怎麼自定義縮放Win10
- 深度學習影象視訊壓縮演算法——TNG深度學習演算法
- Flutter 自定義縮放控制元件Flutter控制元件
- Canvas 縮放圖片中細節消失Canvas
- Flutter螢幕適配 - 等比縮放Flutter