2

私はC#で描画プログラムのプロトタイプに取り組んでいます。

マウスの位置に従って、目的の画像にブレンドする「ブラシ」画像を生成します。動作しますが、同じ場所で何度もブレンドするとアーティファクトが生成されます。特に、ブラシの透明なピクセルは、宛先の画像を暗くする傾向があります。

これが、アーティファクトのあるブラシと宛先画像です。右側は対応するアルファチャンネルです。最後の行は、フラットブラシ(半透明のディスク)を使用した場合の正しい結果を示しています。

バグの図解

この問題を説明するサンプルプログラムを作成しました。

public static Bitmap GenerateBrush(double radius, Func<double, double, double> curve)
{
    int npx = (int)Math.Ceiling(radius) * 2 + 1;
    Bitmap bmp = new Bitmap(npx, npx, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    for (int ix = 0; ix < npx; ix++) {
        for (int iy = 0; iy < npx; iy++) {
            double fx = 2.0 * ix / (double)(npx - 1) - 1.0;
            double fy = 2.0 * iy / (double)(npx - 1) - 1.0;
            double res = curve(fx, fy);
            bmp.SetPixel(ix, iy, Color.FromArgb((int)(res * 255), 255, 255, 255));
        }
    }
    return bmp;
}

static void Main(string[] args)
{
    var bmpDest = new Bitmap(200, 200, PixelFormat.Format32bppArgb);
    var graphDest = Graphics.FromImage(bmpDest);
    graphDest.Clear(Color.FromArgb(0, 255, 255, 255));

    var bmpSrc = GenerateBrush(40, delegate(double x, double y) {
        double d = Math.Max(1.0 - Math.Sqrt(x * x + y * y), 0.0);
        return 0.5 + Math.Sin((d - 0.5) * Math.PI) / 2;
    });
    
    var im = new ImageAttributes();
    im.SetColorMatrix(new ColorMatrix(
        new float[][] {
        new float[] { 1, 0, 0, 0, 0 },
        new float[] { 0, 1, 0, 0, 0 },
        new float[] { 0, 0, 0, 0, 0 },
        new float[] { 0, 0, 0, 0.3f, 0 },
        new float[] { .0f, .0f, .0f, .0f, 1 }
        }
    ));

    int nsteps = 2000;
    for (int i = 0; i < nsteps; i++) {
        var t = i / (float)nsteps;
        var xpos = 60 + (int)(Math.Sin(t*Math.PI*40) * 50);
        var ypos = 60 + (t>0.5 ? 20: -20);
        graphDest.DrawImage(bmpSrc, new Rectangle(xpos, ypos, 100, 100), 0, 0, 100, 100, GraphicsUnit.Pixel, im);
    }

    bmpDest.Save(@"test.png");
}

GDI+が透明な画像をブレンドする方法の精度の問題が原因である可能性があるように私には思えます。何かご意見は?

- 編集

カラーマトリックスなしの同じ問題(DrawImage()の最後の引数を削除):

ここに画像の説明を入力してください

-編集2

誰もこれに対する答えを持っていないようです-質問は十分に明確ではありませんか?

4

2 に答える 2

1

はい、切り捨てエラーが蓄積されています。画像にモードを使用してみてPixelFormat.Format32bppPArgbください。しかし、それが役立つかどうかはわかりません。

確実な解決策は、ブラシストロークを単一チャネルの画像に蓄積し、その結果をマスクとして使用してキャンバスにペイントすることです。

于 2012-06-07T21:33:57.487 に答える
0

グラフィックオブジェクトのSmoothingModeを調整してみましたか?ブラシを左から右に動かすと、追加の補間が発生する可能性があるようです。

于 2012-06-02T10:41:11.980 に答える