Marco
Marco

Reputation: 57573

Image from byte array

I need to render an image in an ObjectListView column, so I set an ImageRenderer that accepts a byte array and use this code to change it into an image

image = Image.FromStream(stream);

That said, I need to extract an icon from an exe file, convert it into a byte array so that ObjectListView can render it.
Here is the code I use:

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

Problem is that image is rendered with wrong colors (like if it was 8bpp).
So I tried to use this code to find the problem:

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

In this scenario, img1.bmp is correct (bitmap with real colors), while img2.bmp has wrong colors; so either ms.ToArray() or Image.FromStream corrupt the image.

SOLUTION:
Solution given by Steven Doggart solves problem of colors, but rendered image is not "transparent".
A possible solution is making the bitmap transparent and passing a PNG format to the array

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

Upvotes: 3

Views: 2869

Answers (1)

Steven Doggart
Steven Doggart

Reputation: 43743

The problem is that you are saving an Icon to a byte array, but then you are loading it from that byte array directly into an Image. Icon objects are not stored in the same byte-array format as Image objects. Icon objects can contain multiple images of different sizes and color depths whereas Image objects can only contain one. Also, Icon objects accept the alpha channel (transparency) whereas Image objects do not.

When you save the Icon to the byte array, you should first extract the desired bitmap from it, like this:

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

Upvotes: 2

Related Questions