C#で画像を拡大した場合にずれる問題の原因と対処方法

C#でプログラミングをしていて遭遇した問題についてです。

画像を拡大した場合、よく見ると微妙に画像がずれている場合があります。
アンチエイリアスを効かせていると分かりにくいかもしれませんが、ドット絵を拡大するような場合にはこの現象が分かりやすいです。

なぜずれるのか、原因と対策について書きます。

サンプル

実際に見てもらったほうが早いと思うのでサンプルを作ってみました。
実際にサンプルを動かさなくても画像だけでも分かると思います。

なお、サンプルは適当にピクチャーボックスを設置してください。

サンプルコード

private void Form1_Load(object sender, EventArgs e)
{
    Bitmap bmp1 = new Bitmap(2, 2);
    Bitmap bmp2 = new Bitmap(pictureBox1.Width, pictureBox1.Height);
    Graphics g = Graphics.FromImage(bmp2);

    bmp1.SetPixel(0, 0, Color.Blue);
    bmp1.SetPixel(1, 1, Color.Red);
    bmp1.SetPixel(1, 0, Color.White);
    bmp1.SetPixel(0, 1, Color.Black);

    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
    //g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;

    g.DrawImage(bmp1, 0, 0, bmp2.Width, bmp2.Height);

    pictureBox1.Image = bmp2;

    g.Dispose();
    bmp1.Dispose();
}

実行結果

ずれている場合

拡大表示でずれる

見事にずれています。

正しく表示されている場合

ずれないで正しく表示される

本来このように表示されるはずでした。
対策すればこのように正しく表示されます。

サンプルの解説

原因の前に

サンプルではドットを拡大してギザギザになるよう補間方法を最近傍補間(Nearest neighbor)にしています。
これに設定しないとギザギザにならないので分かりにくいです。

補間方法はg.InterpolationModeの部分で設定しています。

原因はPixelOffsetMode

サンプルを実行させるとずれていることが分かると思います。
これはPixelOffsetModeの設定が原因です。
それ以上の詳しい原因は私の知識では分からないので申し訳ないです。

対策

PixelOffsetModeをHalfかHighQualityに設定することで解決できました。
Halfのほうが処理が速そうですし、Halfでよろしいかと思います。

サンプルでコメントアウトしてある行のコメントを解除してみてください。
デフォルトの設定でずれて表示されていたものが正しく表示されます。

まとめ

PixelOffsetModeをHalfかHighQualityに設定すれば解決できます。

今回はC#の場合を取り上げてみましたが、確認していませんけどVB.netでも同様の問題が生じると思います。
解決方法も同じでしょう。

画像を拡大表示させてズレに悩んでいた人も、これで大丈夫ですね。

スポンサーリンク
レクタングル(大)
レクタングル(大)

フォローする

スポンサーリンク
レクタングル(大)