Browse Source

use Bicubic to resize images

Scott Brogden 8 years ago
parent
commit
bbe9aab970
2 changed files with 78 additions and 18 deletions
  1. 64 16
      BitmapHelper.cpp
  2. 14 2
      ImageViewer.cpp

+ 64 - 16
BitmapHelper.cpp

@@ -73,22 +73,70 @@ BOOL CBitmapHelper::GetCBitmap(void	*pClip2, CDC *pDC, CBitmap *pBitMap, int nMa
 			
 			if(pBitMap)
 			{
-				pBitMap->CreateCompatibleBitmap(pDC, nWidth, nHeight);
-				ASSERT(pBitMap->m_hObject != NULL);
-
-				CDC MemDc;
-				MemDc.CreateCompatibleDC(pDC);
-
-				CBitmap* oldBitmap = MemDc.SelectObject(pBitMap);	
-			
-				::StretchDIBits(MemDc.m_hDC,
-					0, 0, 
-					nWidth, nHeight,
-					0, 0, lpBI->bmiHeader.biWidth, 
-					lpBI->bmiHeader.biHeight,
-					pDIBBits, lpBI, DIB_PAL_COLORS, SRCCOPY);
-
-				MemDc.SelectObject(oldBitmap);
+				if (nMaxHeight < INT_MAX)
+				{
+					//first create a bitmap of the real size, this is used to pass into Gdiplus::Bitmap to resize more accuratly
+					CBitmap tmp;
+					tmp.CreateCompatibleBitmap(pDC, lpBI->bmiHeader.biWidth, lpBI->bmiHeader.biHeight);
+					ASSERT(tmp.m_hObject != NULL);
+
+					CDC MemDc;
+					MemDc.CreateCompatibleDC(pDC);
+
+					CBitmap* oldBitmap = MemDc.SelectObject(&tmp);			
+				
+					::StretchDIBits(MemDc.m_hDC,
+						0, 0, 
+						lpBI->bmiHeader.biWidth, lpBI->bmiHeader.biHeight,
+						0, 0, lpBI->bmiHeader.biWidth, 
+						lpBI->bmiHeader.biHeight,
+						pDIBBits, lpBI, DIB_PAL_COLORS, SRCCOPY);
+
+					MemDc.SelectObject(oldBitmap);
+
+				
+					//do the resize
+					pBitMap->CreateCompatibleBitmap(pDC, nWidth, nHeight);
+					ASSERT(pBitMap->m_hObject != NULL);
+
+					CDC MemDc2;
+					MemDc2.CreateCompatibleDC(pDC);
+
+					CBitmap* oldBitmap2 = MemDc2.SelectObject(pBitMap);
+
+					HBITMAP h = (HBITMAP)tmp;
+					Gdiplus::Bitmap gdipBitmap(h, NULL);
+
+					Gdiplus::ImageAttributes attrs;
+					Gdiplus::Rect dest(0, 0, nWidth, nHeight);
+
+					Gdiplus::Graphics graphics(MemDc2);
+					graphics.SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic);
+					graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf);
+
+					graphics.DrawImage(&gdipBitmap, dest, 0, 0, lpBI->bmiHeader.biWidth, lpBI->bmiHeader.biHeight, Gdiplus::UnitPixel, &attrs);
+
+					MemDc2.SelectObject(oldBitmap2);
+				}
+				else
+				{
+					pBitMap->CreateCompatibleBitmap(pDC, nWidth, nHeight);
+					ASSERT(pBitMap->m_hObject != NULL);
+
+					CDC MemDc;
+					MemDc.CreateCompatibleDC(pDC);
+
+					CBitmap* oldBitmap = MemDc.SelectObject(pBitMap);
+
+					::StretchDIBits(MemDc.m_hDC,
+						0, 0,
+						lpBI->bmiHeader.biWidth, lpBI->bmiHeader.biHeight,
+						0, 0, lpBI->bmiHeader.biWidth,
+						lpBI->bmiHeader.biHeight,
+						pDIBBits, lpBI, DIB_PAL_COLORS, SRCCOPY);
+
+					MemDc.SelectObject(oldBitmap);
+				}
 
 				bRet = TRUE;
 			}

+ 14 - 2
ImageViewer.cpp

@@ -112,9 +112,12 @@ void CImageViewer::OnPaint()
 
 		int width = CBitmapHelper::GetCBitmapWidth(*m_pBitmap);
 		int height = CBitmapHelper::GetCBitmapHeight(*m_pBitmap);
-
+		
 		if (CGetSetOptions::GetScaleImagesToDescWindow())
 		{
+			HBITMAP h = (HBITMAP)*m_pBitmap;
+			Gdiplus::Bitmap gdipBitmap(h, NULL);
+
 			double newWidth = rect.Width();
 			double newHeight = rect.Height();
 
@@ -135,8 +138,17 @@ void CImageViewer::OnPaint()
 					newWidth = (rect.Height() * width) / height;
 				}
 			}
+
+			Gdiplus::ImageAttributes attrs;
+			Gdiplus::Rect dest(0, 0, newWidth, newHeight);
+
+			Gdiplus::Graphics graphics(dc);
+			graphics.SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic);
+			graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf);
+
+			graphics.DrawImage(&gdipBitmap, dest, 0, 0, width, height, Gdiplus::UnitPixel, &attrs);
 			
-			dc.StretchBlt(rect.left, rect.top, newWidth, newHeight, &MemDc, 0, 0, width, height, SRCCOPY);
+			//dc.StretchBlt(rect.left, rect.top, newWidth, newHeight, &MemDc, 0, 0, width, height, SRCCOPY);
 			//OutputDebugString(StrF(_T("scaling image, window size %d/%d, image %d/%d\n"), min(nWidth, rect.Width()), min(nHeight, rect.Height()), nWidth, nHeight));
 		}
 		else