Setting image palette throws GDI+ generic error exception if the image doesn't have a stream

淺唱寂寞╮ 提交于 2019-12-12 01:08:16

问题


I'm using GDI+ to render a few images onto a bitmap, then render the bitmap onto a panel to use as an editor.

When an image in the editor panel is selected, it should highlight red. I had this working using the following code

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

This was working when I was loading the image using Image.FromFile, which locks the file up, which I don't want. I changed the code to load the image into a temporary image using a steam, clone this into the other image, then dispose of the temporary image. However, now when I hit the line

redImage.Palette = pal

I get a generic GDI+ error. Anyone whose hit one of these will know they give basically no more information than "something broke." I'm not sure why changing the palette would work in the original, but not the cloned image. Can anyone help me out here?

It should be noted that the images are 1 bit per pixel indexed if it makes a difference.

Thanks in advance.


回答1:


What's the difference between Bitmap(Image) and Bitmap.Clone()

It is the difference between a deep and a shallow copy. Bitmap.Clone() is a shallow copy that doesn't copy the pixel data of the bitmap. It keeps a pointer to the original pixel data. It is really only useful when you use one of the overloads that takes a Rectangle.

Accordingly, Bitmap.Clone() will leave a lock on the underlying source of the pixel data. Like the file from which you loaded the image. Or the stream if you used MemoryStream to the lock on the file. Which does require you to keep the MemoryStream alive. Closing or disposing it will crash your program. Later, when the pixel data is needed. Typically when it is painted.

Avoid all this by creating a deep copy that doesn't lock the file:

    public static Bitmap LoadBitmapWithoutLock(string path) {
        using (var temp = Image.FromFile(path)) {
            return new Bitmap(temp);
        }
    }


来源:https://stackoverflow.com/questions/15267758/setting-image-palette-throws-gdi-generic-error-exception-if-the-image-doesnt-h

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!