GDI+图像缩放问题

4

我有一个应用程序,使用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

我期望这个测试可以画出一个平滑的“三角形”,但是实际上线条的大小并不完全符合目标矩形的规定: http://i.imgur.com/NNpMvmW.png 有没有办法修复这种行为?我需要输出大小完全符合规定的位图(考虑源图像的 alpha 通道,边缘不与背景插值)。
P.S:我必须使用 GDI+,因为实际代码使用了 gdiplus 提供的一些 ImageAttributes。

当目标图像大小约为原始大小的1%时,GDI +缩放方法会创建损坏的图像,我遇到了相同的问题。 - 23W
2个回答

5

好的,所以我试了所有不同选项的可能值,最终找到适合我的那个。

SetSmoothingMode(如Na Na建议的)对图像没有任何视觉效果。

然而,SetInterpolationMode(InterpolationModeBilinear)(或更好的)可以产生精确的图像大小,但它也会插值图像边缘与背景。结果看起来像这样,这不符合我的要求。

最后,设置ImageAttibuteWrapMode选项就可以了:

attrs.SetWrapMode(Gdiplus::WrapModeTileFlipXY);

结果正是我想要的:http://i.imgur.com/rYKwAmZ.png 概述:
使用 InterpolationModeNearestNeighbor 和默认 WrapMode 会导致渲染图像大小不准确。为了避免这种情况,设置 WrapModeTileFlipXY => 其他选项(如 InterpolationMode)可以具有任何所需的值,而不会影响已呈现图像的大小。

1

你尝试过this吗?

抗锯齿平滑方法可能会有所帮助。


这是针对线条、曲线和填充的,不适用于位图。 - Robinson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接