从字节数组中获取图像

3

我需要在ObjectListView列中渲染一张图片,所以我设置了一个接受字节数组的ImageRenderer并使用以下代码将其转换为图片

image = Image.FromStream(stream);

话虽如此,我需要从exe文件中提取一个图标,将其转换为字节数组,以便ObjectListView可以呈现它。
这是我使用的代码:

Using ms = New MemoryStream()
    Dim imageIn = Icon.ExtractAssociatedIcon(exe_path)
    imageIn.Save(ms)
    Return ms.ToArray()
End Using

问题是图片的颜色显示错误(就像它是8bpp一样)。所以我尝试使用以下代码来查找问题:
Using ms = New MemoryStream()
    Dim imageIn = Icon.ExtractAssociatedIcon(exe_path)
    imageIn.Save(ms)

    Dim bmp = imageIn.ToBitmap()
    bmp.Save("img1.bmp")
    Using mt As New MemoryStream(ms.ToArray())
        Dim img = Image.FromStream(mt)
        img.Save("img2.bmp")
    End Using
End Using

在这种情况下,img1.bmp是正确的(具有真实颜色的位图),而img2.bmp的颜色是错误的;因此,ms.ToArray()Image.FromStream会破坏图像。 解决方案: 由Steven Doggart提供的解决方案解决了颜色问题,但呈现的图像不是“透明”的。 一个可能的解决方案是使位图透明并将PNG格式传递给数组。
Using ms = New MemoryStream()
    Dim bmp = Icon.ExtractAssociatedIcon(exe_path).ToBitmap()
    bmp.MakeTransparent(bmp.GetPixel(0, 0))
    bmp.Save(ms, ImageFormat.Png)

    Using mt As New MemoryStream(ms.ToArray())
        Dim img = Image.FromStream(mt)
        img.Save("img2.bmp")
    End Using
End Using

在我看来,“img1.bmp”和“img2.bmp”的区别不在于如何读/写流,而在于如何生成字节数组。如果我正确地阅读了您的代码,“img1.bmp”是通过调用“Bitmap.Save”生成的,而“img2.bmp”是通过调用“Icon.Save”生成的。因此,一个是位图,另一个是图标。这些是两种非常不同的数据格式。 - Steven Doggart
是的@Steven,当然可以,但ObjectListView内部使用Image.FromStream(byte_array),我无法更改它;因此,我需要读取图标,将其转换为可从ObjectListView正确读取和呈现的字节数组... - Marco
1个回答

2
问题在于您正在将一个Icon保存到字节数组中,但是您直接从该字节数组中加载它到一个Image中。Icon对象不以与Image对象相同的字节数组格式存储。Icon对象可以包含多个不同大小和颜色深度的图像,而Image对象只能包含一个。此外,Icon对象接受Alpha通道(透明度),而Image对象则不接受。
当您将Icon保存到字节数组中时,应首先从中提取所需的位图,如下所示:
Using ms = New MemoryStream()
    Dim imageIn = Icon.ExtractAssociatedIcon(exe_path)
    imageIn.ToBitmap().Save(ms, ImageFormat.Bmp)
    Return ms.ToArray()
End Using

谢谢Steven,你说得对,但要小心,我不能使用你的语法;尝试将其更改为imageIn.ToBitmap().Save(ms, ImageFormat.Bmp)。无论如何渲染的位图都不是透明的...需要解决这个问题,但我们正在走上正确的道路! - Marco
我修复了示例以指定格式。谢谢。 - Steven Doggart
透明度问题仍然存在:请阅读我的编辑帖子。谢谢! - Marco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接