3

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

この動作を修正する方法はありますか? 指定されたとおりのサイズのビットマップを出力する必要があります(ソース画像のアルファチャンネルを考慮し、エッジの背景を補間しないことを考慮してください)。

PS: 実際のコードは gdiplus によって提供されるいくつかの ImageAttributes を使用するため、GDI+ を使用する必要があります。

4

2 に答える 2

2

わかりましたので、さまざまなオプションで可能なすべての値を試してみて、最終的に自分に適した値を見つけました。

SetSmoothingMode(Na Na が提案したように) 画像に視覚的な効果はありませんでした。

ただしSetInterpolationMode(InterpolationModeBilinear)(またはそれ以上)正確な画像サイズを生成しますが、画像のエッジを背景で補間します。結果は次のようになりますが、これは私の要件には合いません。

最後に、ImageAttibuteWrapModeオプションを設定するとうまくいきます。

attrs.SetWrapMode(Gdiplus::WrapModeTileFlipXY);

結果はまさに私が望んでいたものです: http://i.imgur.com/rYKwAmZ.png

概要:

InterpolationModeNearestNeighbor デフォルトを使用すると、WrapModeレンダリング イメージのサイズが不正確になります。これを回避するには、set WrapModeTileFlipXY=> 他のオプション ( などInterpolationMode) に、レンダリングされたイメージのサイズに影響を与えずに任意の値を設定できます。

于 2013-09-07T17:45:15.467 に答える
1

これを試しましたか?

アンチエイリアシング スムージング メソッドが役立つ場合があります。

于 2013-09-06T17:42:47.507 に答える