nev*_*ind 4 c++ scaling gdi+ image bitmap
我有一个使用 gdi+ 从某些位图绘制背景的应用程序。一些位图是垂直非线性渐变(例如,它们是 1 像素宽,应该水平拉伸以填充整个控件宽度)。问题在于,对于小图像(如上所述),右侧的某些控制区域未绘制。
我编写了一个测试程序,将 1x1 图像缩放到不同的尺寸,它表明当比例因子足够大时会出现问题
void Draw(HDC hDestDC, int destleft, int desttop, int destwidth, int destheight)
{
COLORREF buffer[] = {0xFF0000FF }; // 1 pixel image
const int width = 1, height = 1;
Gdiplus::Bitmap gdipBitmap(width, height, 4*width, PixelFormat32bppARGB, (BYTE*)buffer);
Gdiplus::ImageAttributes attrs;
Gdiplus::Rect dest(destleft, desttop, destwidth, destheight);
Gdiplus::Graphics graphics(hDestDC);
graphics.SetInterpolationMode(Gdiplus::InterpolationModeNearestNeighbor);
graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf);
graphics.DrawImage(&gdipBitmap, dest, 0, 0, width, height, Gdiplus::UnitPixel, &attrs);
}
// OnPaint:
for(int i=0; i<800; ++i)
Draw(hdc, 0, i, i, 1); // scale 1x1 image to different width
Run Code Online (Sandbox Code Playgroud)
我希望这个测试能够绘制一个平滑的“三角形”,但线条的大小并不完全按照目标矩形指定: https ://i.stack.imgur.com/Q9rev.png
有什么办法可以纠正这种行为吗?我需要输出大小与指定完全相同的位图(考虑源图像 alpha 通道并且边缘没有背景插值)。
PS:我必须使用GDI+,因为实际代码使用gdiplus提供的一些ImageAttributes。
好的,所以我最终尝试了不同选项的所有可能值,并最终找到了适合我的值。
SetSmoothingMode(正如娜娜所建议的)对图像没有任何视觉效果。
然而SetInterpolationMode(InterpolationModeBilinear)(或更好)产生精确的图像尺寸,但它也用背景插入图像边缘。结果是这样的,不符合我的要求。
最后,设置ImageAttibute的WrapMode选项可以解决问题:
attrs.SetWrapMode(Gdiplus::WrapModeTileFlipXY);
Run Code Online (Sandbox Code Playgroud)
结果正是我想要的: https: //i.stack.imgur.com/umfw3.png
使用默认值InterpolationModeNearestNeighbor 会WrapMode导致渲染图像尺寸不准确。为了避免这种情况, set WrapModeTileFlipXY=> 其他选项(例如InterpolationMode)可以具有任何所需的值,而不影响渲染图像的大小。