由于DrawImage指定destRect和srcRect绘制后,会自动把原图放大到destRect的大小,实现了放大效果,这是很通常的做法;
但如果要求放大得很精确的时候,比如需要将原图放大到destRect后再平铺到整个窗口,这里面其实有个很严重的问题;
比如运行一下如下代码:
if (g_pSrcImage != NULL) { Graphics graphics(hDC); Rect zoomRect(0, 0, g_pSrcImage->GetWidth() * 7, g_pSrcImage->GetHeight() * 7); Bitmap* pImageScale = new Bitmap(zoomRect.Width, zoomRect.Height); if (pImageScale != NULL) { Graphics graphicsScale(pImageScale); graphicsScale.Clear(Color(0, 255, 0)); //填充绿色 graphicsScale.DrawImage(g_pSrcImage, zoomRect, 0, 0, g_pSrcImage->GetWidth(), g_pSrcImage->GetHeight(), UnitPixel); graphics.DrawImage(pImageScale, 0, 0, zoomRect.X, zoomRect.Y, zoomRect.Width, zoomRect.Height, UnitPixel); delete pImageScale; pImageScale = NULL; } }这是一个典型的通过DrawImage等比放大的代码,但实际结果是zoomRect并没有被充满,右边和下边都多出了几个像素预填充的绿色;
再拿这张放大后的图去平铺那就大悲剧了,好多绿色分割线……
解决办法是先使用ScaleTransform设置放大比例,再用FillRectangle把原图填充到zoomRect,代码如下:
if (g_pSrcImage != NULL) { Graphics graphics(hDC); Rect zoomRect(0, 0, g_pSrcImage->GetWidth() * 7, g_pSrcImage->GetHeight() * 7); Bitmap* pImageScale = new Bitmap(zoomRect.Width, zoomRect.Height); if (pImageScale != NULL) { Graphics graphicsScale(pImageScale); graphicsScale.Clear(Color(0, 255, 0)); //填充绿色 // 方法一:正确方法 TextureBrush brush(g_pSrcImage); graphicsScale.ScaleTransform((REAL)((REAL)zoomRect.Width / (REAL)g_pSrcImage->GetWidth()), (REAL)((REAL)zoomRect.Height / (REAL)g_pSrcImage->GetHeight())); graphicsScale.FillRectangle(&brush, zoomRect); // 方法二:右边和下边会有几个像素预填充的绿色 //graphicsScale.DrawImage(g_pSrcImage, zoomRect, 0, 0, g_pSrcImage->GetWidth(), g_pSrcImage->GetHeight(), UnitPixel); graphics.DrawImage(pImageScale, 0, 0, zoomRect.X, zoomRect.Y, zoomRect.Width, zoomRect.Height, UnitPixel); delete pImageScale; pImageScale = NULL; } }