【问题标题】:Setting image palette throws GDI+ generic error exception if the image doesn't have a stream如果图像没有流,则设置图像调色板会引发 GDI+ 通用错误异常
【发布时间】:2013-03-07 09:42:32
【问题描述】:

我正在使用 GDI+ 将一些图像渲染到位图上,然后将位图渲染到面板上以用作编辑器。

When an image in the editor panel is selected, it should highlight red.我使用以下代码进行了这项工作

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 位索引的。

提前致谢。

【问题讨论】:

  • 您遗漏了最重要的代码。确保您没有处置 MemoryStream。并且喜欢使用 Bitmap(Image) 构造函数而不是 Bitmap.Clone() 来复制图像。这也可以防止文件被锁定。
  • Bitmap(Image) 和 Bitmap.Clone() 有什么区别?问题是我想关闭内存流以便其他东西可以访问该文件?我只想将图像加载到程序中,然后将其存储在 ram 中,而不是链接到文件。我认为我这样做的方式会允许这样做吗?

标签: .net vb.net winforms gdi+


【解决方案1】:

Bitmap(Image) 和 Bitmap.Clone() 有什么区别

这是 deepshallow 副本之间的区别。 Bitmap.Clone() 是一个浅拷贝,不拷贝位图的像素数据。它保留一个指向原始像素数据的指针。仅当您使用采用 Rectangle 的重载之一时,它才真正有用。

因此,Bitmap.Clone() 将锁定像素数据的底层源。就像您从中加载图像的文件一样。或者如果您使用 MemoryStream 锁定文件,则使用流。 确实要求您保持 MemoryStream 处于活动状态。关闭或处理它会使你的程序崩溃。稍后,当需要像素数据时。通常在上漆时。

通过创建不锁定文件的深层副本来避免所有这些:

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

【讨论】:

  • 啊,好吧,我的印象是相反(克隆创建一个深层副本),但我想不是。似乎当我以这种方式复制时,图像失去了像素格式,因此没有调色板。不过,我会将您的答案标记为已回答,并尝试找到解决问题的另一种方法。
猜你喜欢
  • 2010-10-23
  • 2019-01-03
  • 1970-01-01
  • 2013-05-07
  • 2015-01-27
  • 2016-10-20
  • 1970-01-01
  • 1970-01-01
  • 2017-08-18
相关资源
最近更新 更多