C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: GDI+で画像サイズを大きくした時に出る画像端の帯の消し方


(過去ログ 173 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■99490 / inTopicNo.1)  GDI+で画像サイズを大きくした時に出る画像端の帯の消し方
  
□投稿者/ yao (1回)-(2022/04/16(Sat) 19:11:08)

分類:[.NET 全般] 

2022/04/16(Sat) 19:45:21 編集(投稿者)

あああ
引用返信 編集キー/
■99492 / inTopicNo.2)  Re[1]: GDI+で画像サイズを大きくした時に出る画像端の帯の消し方
□投稿者/ ???? (6回)-(2022/04/17(Sun) 05:52:19)
No99490 (yao さん) に返信
> 2022/04/16(Sat) 19:45:21 編集(投稿者)
>
> あああ
解決済み
引用返信 編集キー/
■99494 / inTopicNo.3)  Re[2]: GDI+で画像サイズを大きくした時に出る画像端の帯の消し方
□投稿者/ yao (2回)-(2022/04/17(Sun) 18:15:48)
VB.NETを使って、
30x30ピクセル程度の小さなピクセル数の画像を
880x880ピクセル程度まで大きくしたいと考えています。

以下のようなコードで30x30ピクセルのimgを
880x880程度のサイズのPictureBoxと同じサイズまで拡大してみました。

	Dim img As Bitmap

	Dim PBox As PictureBox = PictureBox1


        Dim canvas As New Bitmap(PBox.ClientSize.Width, PBox.ClientSize.Height, PixelFormat.Format32bppPArgb)

        Using g As Graphics = Graphics.FromImage(canvas)

            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor
            ' g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear

            g.PixelOffsetMode = PixelOffsetMode.HighQuality
            g.DrawImage(img, 0, 0, PBox.ClientSize.Width, PBox.ClientSize.Height)


            img.Dispose()

        End Using

	PBox.Image = canvas


すると、
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor
の場合には、綺麗に拡大することができました。
https://dotup.org/uploda/dotup.org2778352.png


しかし
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear
の場合には、画像の4隅がぼやけてしまいます。
https://dotup.org/uploda/dotup.org2778353.png
PictureBox全体に渡って綺麗に画像を拡大したいのですが
どのようにすれば良いですか?

引用返信 編集キー/
■99495 / inTopicNo.4)  Re[3]: GDI+で画像サイズを大きくした時に出る画像端の帯の消し方
□投稿者/ 魔界の仮面弁士 (3325回)-(2022/04/18(Mon) 12:04:16)
2022/04/18(Mon) 12:56:10 編集(投稿者)

No99494 (yao さん) に返信
> 30x30ピクセル程度の小さなピクセル数の画像を
結果画像は御提示頂きましたが、実験に用いられた
変換元の 30x30 の画像の内容が示されていません。
「Dim img As Bitmap」の変数の中身も空のままですよね。Dispose はしているのに。

恐らくは img は 30x30 サイズでアリ、全ピクセルが同一色なのだろうとは想像できますが、
中身は、不透過 (Alpha 値 = 255)な緑 (R = 89, G = 201, B = 0)ということでしょうか?

元画像が、不透明ではない場合(完全透過や半透過部を含む場合)、話がややこしくなりそうで…。


> 880x880ピクセル程度まで大きくしたいと考えています。
提示の画像は正方形ではなく、878x877 ピクセルのようですね。


> g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear
> の場合には、画像の4隅がぼやけてしまいます。
> https://dotup.org/uploda/dotup.org2778353.png
四隅ではなく四辺ですよね。

提示の画像だと、すべての座標で Alpha 値が 255 の不透過画像となっていましたが、
本来は周辺部が半透明画像になるはずです。PictureBox1 の BackColor を Blue などにして試してみてください。

提示された画像では、PictureBox1 の BorderStyle = FixedSingle が映りこんでいるようにみえるので、
恐らくは画像そのものを保存せずに、画面のキャプチャなどを行っているのだと思います。
それだと、拡大補完の問題なのか、画像の取り扱いの問題なのかを判断しにくくなってしまうので、
canvas.Save して、補完画像自体を保管するようにしてみた方が良いでしょう。

たとえば、DrawImage する前に
 g.Clear(Color.FromArgb(128, Color.Red))
 ' g.Clear(Color.FromArgb(89, 201, 0))
を入れておいたら、周辺部が赤みを帯びたグラデーションに変わると思います。


> PictureBox全体に渡って綺麗に画像を拡大したいのですが
何をもって「綺麗」と見做すかは、画像の特性によって一長一短かと思います。

NearestNeighbor (最近傍補間)法は、シャープな輪郭となるのが特徴で、
2 の倍数単位に拡大すると、画像の角ばった感じがそのまま受け継がれます。
ジャギーが目立つので自然写真には向きませんが、ドット絵の拡大には有効です。

Bilinear (双一次補間)法の場合、求める位置周辺の画素を拾って
直線的な算出する補完方式のため、滑らかなグラデーションを描きますが、
ドット絵に対しては、ぼやけた感じが強く出るため向きません。

また NearestNeighbor 以外の場合、グラデーションの流れは画素の補完方向に依存します。
その特性上、拡大率が高い場合、画素の不足する周辺部が半透明化することになり、
PixelOffsetMode = None の場合は、右端と下端のみが半透明化することになり、
PixelOffsetMode = Half の場合は、四辺が半透明化します。(距離にも差が出ます)


> PictureBox全体に渡って綺麗に画像を拡大したいのですが
> どのようにすれば良いですか?
半透明であることを利用して、重ね描きすれば多少軽減できるかもしれません。

g.InterpolationMode = InterpolationMode.NearestNeighbor
g.PixelOffsetMode = PixelOffsetMode.Half
g.DrawImage(img, 0, 0, PBox.ClientSize.Width, PBox.ClientSize.Height)
g.InterpolationMode = InterpolationMode.Bilinear
g.PixelOffsetMode = PixelOffsetMode.HighQuality
g.DrawImage(img, 0, 0, PBox.ClientSize.Width, PBox.ClientSize.Height)
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -