■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)
|
|