私のWindowsフォームプログラムには、がありPictureBox
ます。その中のビットマップ画像は小さい5 x 5
ピクセルです。
に割り当てると、PictureBox
非常にぼやけます。
ブレンディングモード、ブラーモード、アンチエイリアシングモードなどを見つけてみましたが、うまくいきませんでした。
This is what I want This is not what I want
問題:
表示に使用されるコンテナよりもはるかに小さいサイズのビットマップがぼやけており、明確に定義された色の領域の鋭いエッジが不用意にブレンドされています。
これは、ズームインしたときに非常に小さい画像(数ピクセル)にバイリニアフィルターを適用した結果です。
望ましい結果は、代わりに、画像が拡大されている間、単一ピクセルの元の色を維持することです。
この結果を得るには、GraphicsオブジェクトのInterpolationModeを次のように設定するだけで十分です。
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor
このフィルターは、とも呼ばれPoint Filter
、評価されるピクセルの色に最も近い色を選択するだけです。色の均一な領域を評価すると、結果はすべてのピクセルで同じピクセル色になります。
問題は1つだけです。それは、GraphicsオブジェクトのPixelOffsetModeのデフォルト値です。
e.Graphics.PixelOffsetMode = PixelOffsetMode.None
このモードをアクティブにすると、(通常の画像サンプリングでは)画像の上部と左側の境界に対応する外側のピクセルが、コンテナ(宛先ビットマップまたはデバイスコンテキスト)によって定義された長方形領域のエッジの中央に描画されます。 。
このため、ソース画像が小さく、そのピクセルがかなり拡大されているため、最初の水平線と垂直線のピクセルが視覚的に半分にカットされます。
これは、他の 方法を使用して解決できますPixelOffsetMode
。
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half
このモードでは、画像のレンダリング位置が0.5ピクセル戻ります。
結果のサンプル画像は、これをよりよく説明できます。
Default Filter InterpolationMode InterpolationMode
InterpolationMode NearestNeighbor NearestNeighbor
Bilinear PixelOffsetMode.None PixelOffsetMode.Half
注:
.NetのMSDNドキュメントでは、PixelOffsetMode
パラメーターについて十分に説明されていません。あなたは6つの明らかに異なる選択肢を見つけることができます。ピクセルオフセットモードは、実際には
PixelOffsetMode.None
(デフォルト)との2つだけですPixelOffsetMode.Half
。
PixelOffsetMode.Default
とPixelOffsetMode.HighSpeed
はと同じPixelOffsetMode.None
です。
PixelOffsetMode.HighQuality
と同じPixelOffsetMode.Half
です。
.Net Docsを読むと、どちらかを選択するときに速度に影響があるようです。違いは実際にはごくわずかです。
本件に関するC ++のドキュメント(一般的にはとGDI +)は、はるかに明示的かつ正確である、それは代わりに、ネットの1の使用すべきです。
進め方:
小さなソースビットマップを新しい大きなビットマップに描画し、それをPictureBox.Image
プロパティに割り当てることができます。
ただし、ある時点でPictureBoxのサイズが変更されたと仮定します(レイアウトが変更されたため、および/またはDPI認識が損なわれたため)、(ほぼ)正方形に戻ります。
簡単な解決策は、新しいビットマップをコントロールの表面に直接描画し、必要に応じてディスクに保存することです。
これにより、品質を損なうことなく、必要に応じてビットマップをスケーリングすることもできます。
Imports System.Drawing
Imports System.Drawing.Drawing2D
Private pixelBitmap As Bitmap = Nothing
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
pixelBitmap = DirectCast(New Bitmap("File Path").Clone(), Bitmap)
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half
e.Graphics.DrawImage(pixelBitmap, GetScaledImageRect(pixelBitmap, DirectCast(sender, Control)))
End Sub
Private Sub PictureBox1_Resize(sender As Object, e As EventArgs) Handles PictureBox1.Resize
PictureBox1.Invalidate()
End Sub
GetScaledImageRect
コンテナ内の画像を拡大縮小するために使用されるヘルパーメソッドです。
Public Function GetScaledImageRect(image As Image, canvas As Control) As RectangleF
Return GetScaledImageRect(image, canvas.ClientSize)
End Function
Public Function GetScaledImageRect(image As Image, containerSize As SizeF) As RectangleF
Dim imgRect As RectangleF = RectangleF.Empty
Dim scaleFactor As Single = CSng(image.Width / image.Height)
Dim containerRatio As Single = containerSize.Width / containerSize.Height
If containerRatio >= scaleFactor Then
imgRect.Size = New SizeF(containerSize.Height * scaleFactor, containerSize.Height)
imgRect.Location = New PointF((containerSize.Width - imgRect.Width) / 2, 0)
Else
imgRect.Size = New SizeF(containerSize.Width, containerSize.Width / scaleFactor)
imgRect.Location = New PointF(0, (containerSize.Height - imgRect.Height) / 2)
End If
Return imgRect
End Function
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加