GDI +图像缩放问题

时间:2013-09-05 18:32:38

标签: c++ image bitmap gdi+ scaling

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

我会检测此测试以绘制一个平滑的“三角形”,但相反的行不具有目标rect指定的完全大小: http://i.imgur.com/NNpMvmW.png

有没有办法解决这个问题?我需要输出完全符合指定大小的位图(考虑源图像alpha通道,边缘没有背景插值)。

P.S:我必须使用GDI +,因为实际代码使用了gdiplus提供的一些ImageAttributes。

2 个答案:

答案 0 :(得分:2)

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

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

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

最后,设置ImageAttibute的{​​{1}}选项可以解决问题:

WrapMode

结果正是我想要的:http://i.imgur.com/rYKwAmZ.png

要点:

使用attrs.SetWrapMode(Gdiplus::WrapModeTileFlipXY); 默认InterpolationModeNearestNeighbor会导致渲染图片大小不准确。为避免这种情况,请设置WrapMode =&gt;其他选项(如WrapModeTileFlipXY)可以具有任何所需的值,而不会影响渲染的图像大小。

答案 1 :(得分:1)

您是否尝试过this

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