views:

212

answers:

3

I am trying to read in the pixel data from an image file as a byte[], for in-memory storage. (The byte array will later be fed to a bitmap image object, but I want the data in memory so that there's no I/O holdup.)

This is what I'm currently doing:

private byte[] GetImageBytes(Uri imageUri) {

     //arraySize and stride previously defined

    var pixelArray = new byte[arraySize];
    new BitmapImage(imageUri).CopyPixels(pixelArray , stride, 0);

    return pixelArray ;
}

I am wondering if someone knows of a way to get the byte[] data other than making a BitmapImage and then copying all of the bytes out. I.e. is there a .NET class that will just stream pixel data from the file? (I was originally using File.ReadAllBytes, but that brings in other stuff like the image metadata, and wasn't working out.)

A: 

Have you played around with the ImageConverter class in System.Drawing?

You might be able to do something like

private byte[] GetImageBytes(Uri imageUri) {

ImageConverter ic = new ImageConverter(); return (byte[])ic.ConvertTo(imageUri, typeof(byte[])); }

There might be some methods relating to copying pixels in the ImageConverter class or in a similar class in System.Drawing

Jason M
No, unfortunately this does not work. It throws an InvalidCastException.
Henry Jackson
have you tried using BitmapSource.CopyPixels?
Jason M
A: 

Have you considered just loading your image into a CachedBitmap instead of using your own caching mechanism?

http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.cachedbitmap.aspx

Darryl Braaten
The reason I read them to a byte array and then later make an image out of that is because images need to be created on the main UI thread, but I want to fetch the image data on a background thread (since they come in over a network, and I don't want to tie up the UI thread fetching data).And I don't see a way to create a new BitmapSource from the CachedBitmap, so I would still need to create a CachedBitmap, copy the pixels out into an array, and then create a new image from that.
Henry Jackson
A CachedBitmap is a BitmapSource
Darryl Braaten
Right... maybe I'm not understanding your answer. My goal is to have some in-memory representation of the image, that I can then use to create the "real" (i.e. displayed) image later on. The point is that the displayed image cannot be created at the same time as the I/O, and I am looking for a convenient and efficient way to get the data into memory at I/O read time. How can the CachedBitmap help me?
Henry Jackson
You should be able to create a CachedBitmap without displaying it. Create it when you want start loading the data. When you want to show the image to the user you can display the already created bitmap. i.e. just have your GetImageFunction return a CachedBitmap When I have some time I will create a code sample.
Darryl Braaten
A: 

I will answer my own question, in case anyone else finds it useful:

The reason I had originally wanted to read the data into a byte array was so that I could do the file or network IO on a background thread. But I have since learned about the Freeze() method, which lets the image be read on a background thread and then shared across threads.

So if I freeze the BitmapImage, the impetus for temporarily storing the data in a byte[] goes away, and the problem is solved.

Henry Jackson