DOBON.NET DOBON.NETプログラミング掲示板過去ログ

バイキュービック法で画像を縮小すると薄い線が入る

環境/言語:[OS : Windows XP Professional / 言語 : Visual Basic .NET / .NET Framework : 1.1]
分類:[.NET]

2006/01/23(Mon) 16:43:52 編集(投稿者)

【解決したい問題】

初めて投稿させて頂きます。
補間方法として高品質双三次補間を指定して画像を縮小すると、画像の左端と上端の1or2ピクセルの位置に1ピクセルの薄い線が入ってしまいます。

g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic

他の補間方法では線は入りません。
これはバイキュービック法の特性で仕方がないのでしょうか?
それとも.NET Frameworkのバージョンの問題でしょうか?
線が入らない何かいい方法がありましたらご教授お願い致します。
> 補間方法として高品質双三次補間を指定して画像を縮小すると、画像の左端と上端の1or2ピクセルの位置に1ピクセルの薄い線が入ってしまいます。

調べてみたところ、そのような問題があるようです。ニュースグループに次のような投稿があり、マイクロソフトの方が回答されています。ただその解決法は、私には理解できません。(WrapModeをWrapModeTileFlipXYにするということらしいですが・・・。)

.NET 247 : poor quality on microsoft.public.dotnet.framework.drawing
http://dotnet247.com/247reference/msgs/18/90735.aspx

また、以下のページのFeedbackでもこの問題が報告されています。解決法も提示されていますが、いかがでしょうか?

Rick Strahl's WebLog
http://west-wind.com/weblog/posts/626.aspx
英語は不得手ですので難航しそうですが、情報を基に頑張ってみます。
ありがとうございました。
解決済み!
やはり「WrapModeをWrapModeTileFlipXYにする」というのが分からなかったので、あまり良い方法とは思えませんが、以下のようにして左辺と上辺を2ピクセル分切り取ることにしました。

g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
g.DrawImage(image, -2, -2, intWidth + 2, intHeight + 2)

Rick Strahl's WebLog では -1 ずらしていましたが、2ピクセルの位置に線が出ることもあるので -2 ずらしました。
上記のようにすると、右端に線が出てしまったので最終的に以下のようにしました。

g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
g.DrawImage(image, -2, -2, intWidth + 3, intHeight + 3)

一応解決にしますが、どうもすっきりしないので、自分の中で未解決事項として引き続きこの件について調べて行きたいと思います。
解決済み!
> やはり「WrapModeをWrapModeTileFlipXYにする」というのが分からなかったので、あまり良い方法とは思えませんが、以下のようにして左辺と上辺を2ピクセル分切り取ることにしました。

後で考えて思ったのですが、縮小する画像をTextureBrushを使ってWrapModeTileFlipXYで塗りつぶした画像を作成し、そのもとの画像の部分を縮小するというような意味かもしれません。つまり、縮小する画像の上と左に何もないことが問題となっているわけですから、この部分に画像を上下(あるいは左右)に反転させたものをコピーしておけばよいということではないでしょうか。
解決済み!
> 後で考えて思ったのですが、縮小する画像をTextureBrushを使ってWrapModeTileFlipXYで塗りつぶした画像を作成し、そのもとの画像の部分を縮小するというような意味かもしれません。つまり、縮小する画像の上と左に何もないことが問題となっているわけですから、この部分に画像を上下(あるいは左右)に反転させたものをコピーしておけばよいということではないでしょうか。

なるほど・・・
早速以下のようにしてうまくいきました。
これで本当に解決です。
ありがとうございました。

<前略>

g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
Dim myBrush As New TextureBrush(image, Drawing2D.WrapMode.TileFlipXY)
g.FillRectangle(myBrush, New Rectangle(intW * -1, intH * -1, intW, intH))
myBrush.Dispose()

<後略>
解決済み!
前に書いたものはかなり省略していますし、実際2行目2列目の画像をセットすると反転した画像になってしまいます。
他の方の参考になるように、改めて実際に組んだソースを載せておきます。
(実際のものと比べると略している部分は沢山ありますが)
初心者ですので、突っ込みどころが沢山あると思いますが、その場合は遠慮なく突っ込みを入れてやって下さい。
よろしくお願いいたします。


'ビットマップオブジェクトの作成
Dim objImg As Bitmap = New Bitmap(strFilePath)

'24ビットのビットマップの作成
Dim objNewImg As Bitmap = New Bitmap(intW, intH, Drawing.Imaging.PixelFormat.Format24bppRgb)
'Graphicsオブジェクトの作成
Dim objGraphics As Graphics = Graphics.FromImage(objNewImg)

'補完方法にバイキュービックを指定
objGraphics.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic

'画像をタイル状に描写する為のビットマップを作成
Dim objTmpImg As Bitmap = New Bitmap(objImg.Width * 4, objImg.Height * 4, Drawing.Imaging.PixelFormat.Format24bppRgb)
Dim objTmpGp As Graphics = Graphics.FromImage(objTmpImg)

'画像をタイル状に描写
Dim myBrush As New TextureBrush(objImg, Drawing2D.WrapMode.TileFlipXY)
objTmpGp.FillRectangle(myBrush, New Rectangle(0, 0, objImg.Width * 4, objImg.Height * 4))

'画像を縮小して3行目の3列目の画像が描写される位置に書き込む
objGraphics.DrawImage(objTmpImg, intW * -2, intH * -2, intW * 4, intH * 4)

'画像を保存する(実際は画質を指定して保存しています)
objNewImg.Save(strPath, ImageFormat.Jpeg)

'オブジェクトの破棄
objTmpImg.Dispose()
objTmpGp.Dispose()
myBrush.Dispose()
objGraphics.Dispose()
objNewImg.Dispose()
objImg.Dispose()
解決済みにしたつもりが、解決済みになっていませんでした。
申し訳ありません。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板