0

GDI+ を使用していくつかの画像をビットマップにレンダリングし、そのビットマップをパネルにレンダリングしてエディターとして使用しています。

エディタ パネルで画像を選択すると、赤色で強調表示されます。次のコードを使用してこれを機能させました

If mCurrentindex = ind Then
    Dim redImage As Bitmap = item.Image.Clone()

    Dim pal As ColorPalette

    pal = redImage.Palette

    For i As Integer = 0 To pal.Entries.Length - 1
        If pal.Entries(i).Name = "ff000000" Then
            pal.Entries(i) = Color.Red
        End If
    Next

    redImage.Palette = pal

    g.DrawImage(redImage, 0, 0, (CType((item.Image.Width), Integer)), (CType((item.Image.Height), Integer)))

    Dim highlightPen As New Pen(Brushes.Red, 2)
    g.DrawRectangle(highlightPen, New Rectangle(0, 0, item.W - 1, item.H - 1))
Else
    g.DrawImage(item.Image, 0, 0, (CType((item.Image.Width), Integer)), (CType((item.Image.Height), Integer)))
End If

これは、Image.FromFile を使用して画像を読み込んでいたときに機能していました。これにより、ファイルがロックされますが、これは望ましくありません。スチームを使用してイメージを一時イメージにロードし、これを他のイメージに複製してから、一時イメージを破棄するようにコードを変更しました。しかし、今私がラインを打つとき

redImage.Palette = pal

一般的な GDI+ エラーが発生します。これらのいずれかにヒットした人は、基本的に「何かが壊れた」以外の情報を提供しないことを知っています。パレットの変更が元の画像では機能するのに、複製された画像では機能しない理由がわかりません。誰か助けてくれませんか?

違いが生じる場合、イメージはインデックス付きのピクセルあたり 1 ビットであることに注意してください。

前もって感謝します。

4

1 に答える 1

0

Bitmap(Image) と Bitmap.Clone() の違いは何ですか

深いコピーと浅いコピーの違いです。Bitmap.Clone() は、ビットマップのピクセル データをコピーしない浅いコピーです。元のピクセル データへのポインターを保持します。Rectangle を受け取るオーバーロードの 1 つを使用する場合にのみ、実際に役立ちます。

したがって、Bitmap.Clone() は、ピクセル データの基になるソースにロックを残します。画像をロードしたファイルのように。または、ファイルのロックに MemoryStream を使用した場合はストリーム。これに、MemoryStream を維持する必要があります。閉じたり破棄したりすると、プログラムがクラッシュします。後で、ピクセルデータが必要になったとき。通常は塗装時です。

ファイルをロックしないディープ コピーを作成することで、これらすべてを回避します。

    public static Bitmap LoadBitmapWithoutLock(string path) {
        using (var temp = Image.FromFile(path)) {
            return new Bitmap(temp);
        }
    }
于 2013-03-07T16:34:23.100 に答える