使用StretchBlt函数进行图像缩放

xiaoxiao2021-02-28  110

原文链接:https://www.oschina.net/code/snippet_222150_16279

1. [代码][C/C++]代码    

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 // Resize CImage void CreateStretchImage(CImage *pImage,CImage *ResultImage, int StretchHeight, int StretchWidth){      if (pImage->IsDIBSection()){            // 取得 pImage 的 DC    CDC* pImageDC1 = CDC::FromHandle(pImage->GetDC()); // Image 因為有自己的 DC, 所以必須使用 FromHandle 取得對應的 DC          CBitmap *bitmap1=pImageDC1->GetCurrentBitmap();    BITMAP bmpInfo;    bitmap1->GetBitmap(&bmpInfo);      // 建立新的 CImage    ResultImage->Create(StretchWidth,StretchHeight,bmpInfo.bmBitsPixel);    CDC* ResultImageDC = CDC::FromHandle(ResultImage->GetDC());      // 當 Destination 比較小的時候, 會根據 Destination DC 上的 Stretch Blt mode 決定是否要保留被刪除點的資訊    ResultImageDC->SetStretchBltMode(HALFTONE); // 使用最高品質的方式    ::SetBrushOrgEx(ResultImageDC->m_hDC,0,0,NULL); // 調整 Brush 的起點      // 把 pImage 畫到 ResultImage 上面    StretchBlt(*ResultImageDC,0,0,StretchWidth,StretchHeight,*pImageDC1,0,0,pImage->GetWidth(),pImage->GetHeight(),SRCCOPY);    // pImage->Draw(*ResultImageDC,0,0,StretchWidth,StretchHeight,0,0,pImage->GetWidth(),pImage->GetHeight());      pImage->ReleaseDC();    ResultImage->ReleaseDC();       } }   // 建立指定大小的圖形 // 輸入: 原始圖檔=pBitmap, 指定大小=StretchHeight StretchWidth, 結果圖檔=pResultBmp // Usage:   void reateStretchBmp(CBitmap* pBitmap , int StretchHeight , int StretchWidth, CBitmap *pResultBmp){   // 建立顯示螢幕的 DC   CDC dcScreen;          dcScreen.Attach(::GetDC(NULL));     // 取得原始圖檔的 dc   CDC dcMemory;          dcMemory.CreateCompatibleDC(&dcScreen);   CBitmap *pOldOrgBitmap= dcMemory.SelectObject(pBitmap);      // 建立新的結果圖形 (指定大小)   pResultBmp->CreateCompatibleBitmap(&dcScreen,StretchWidth,StretchHeight);     // 取得結果圖形的 dc   CDC dcFixMemory;   dcFixMemory.CreateCompatibleDC(&dcScreen);   CBitmap *pOldReslutBitmap=dcFixMemory.SelectObject(pResultBmp); // 讓 dcFixMemory 選擇到 "結果bmp", 任何對 dcFixMemory 的動作都會反映到 pResultBmp     // 把原始圖形縮放畫到 Memory DC上面   BITMAP bmpInfo;   pBitmap->GetBitmap(&bmpInfo); // 取得 原始圖檔的寬度與高度   StretchBlt(dcFixMemory,0,0,StretchWidth,StretchHeight,dcMemory,0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,SRCCOPY);     // Set Back   dcMemory.SelectObject(pOldOrgBitmap);   dcFixMemory.SelectObject(pOldReslutBitmap); }

2. [代码]对整个图片做缩放    

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 unsigned char * HCNImage::do_Stretch_Linear( int w_Dest, int h_Dest, int bit_depth,unsigned char *src, int w_Src, int h_Src) { int sw = w_Src-1, sh = h_Src-1, dw = w_Dest-1, dh = h_Dest-1; int B, N, x, y; int nPixelSize = bit_depth/8; unsigned char *pLinePrev,*pLineNext; unsigned char *pDest = new unsigned char [w_Dest*h_Dest*bit_depth/8]; unsigned char *tmp; unsigned char *pA,*pB,*pC,*pD;   for ( int i=0;i<=dh;++i) { tmp =pDest + i*w_Dest*nPixelSize; y = i*sh/dh; N = dh - i*sh%dh; pLinePrev = src + (y++)*w_Src*nPixelSize;   pLineNext = (N==dh) ? pLinePrev : src+y*w_Src*nPixelSize;   for ( int j=0;j<=dw;++j) { x = j*sw/dw*nPixelSize; B = dw-j*sw%dw; pA = pLinePrev+x; pB = pA+nPixelSize; pC = pLineNext + x; pD = pC + nPixelSize; if (B == dw) { pB=pA; pD=pC; }   for ( int k=0;k<nPixelSize;++k) { *tmp++ = ( unsigned char )( int )( ( B * N * ( *pA++ - *pB - *pC + *pD ) + dw * N * *pB++ + dh * B * *pC++ + ( dw * dh - dh * B - dw * N ) * *pD++ + dw * dh / 2 ) / ( dw * dh ) ); } } } return pDest; }
转载请注明原文地址: https://www.6miu.com/read-37424.html

最新回复(0)