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 的重载之一时,它才真正有用。

因此,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 回答