tags:

views:

76

answers:

3

I've got a byte array for an image (stored in the database). I want to create an Image object, create several Images of different sizes and store them back in the database (save it back to a byte array).

I'm not worried about the database part, or the resizing. But is there an easy way to load an Image object without saving the file to the file system, and then put it back in a byte array when I'm done resizing it? I'd like to do it all in memory if I can.

Something like:
Image myImage = new Image(byte[]);
or
myImage.Load(byte[]);
+3  A: 

You'd use a MemoryStream to do this:

byte[] bytes;
...
using (var ms = new System.IO.MemoryStream(bytes)) {
   using(var img = Image.FromStream(ms)) {
      ...
   }
}
Dave Markle
This will work great. Do you know of a way to get it back into the byte array? After resizing I need to put the resized images back into the database.
Dan Williams
@Dan: Please edit your question to include that.
Adam Robinson
I got it :) Thanks Image.Save(Stream, ImageFormat) - http://msdn.microsoft.com/en-us/library/ms142147.aspx
Dan Williams
This answer is not entirely correct, you are reading image from stream and close this stream afterward. According to MSDN you must keep the stream open for the lifetime of the Image. And for some image formats (not all of them) you definitely need this. So correct method is to create new Bitmap from loaded image, and then dispose both of them stream and original image.
arbiter
@arbiter: Edited to put "img" in a using(){} block. I'd momentarily forgotten it was IDisposable. (Though it will probably work fine if you didn't...) Thanks!
Dave Markle
+2  A: 

Based on your comments to another answer, you can try this for performing a transformation on an image that's stored in a byte[] then returning the result as another byte[].

public byte[] TransformImage(byte[] imageData)
{
    using(var input = new MemoryStream(imageData))
    {
        using(Image img = Image.FromStream(input))
        {
            // perform your transformations

            using(var output = new MemoryStream())
            {
                img.Save(output, ImageFormat.Bmp);

                return output.ToArray();
            }
        }
    }
}

This will allow you to pass in the byte[] stored in the database, perform whatever transformations you need to, then return a new byte[] that can be stored back in the database.

Adam Robinson
A: 

I thought I'd add this as an answer to make it more visible.

With saving it back to a byte array:

    public Image localImage;
    public byte[] ImageBytes;

    public FUU_Image(byte[] bytes)
    {
        using (MemoryStream ImageStream = new System.IO.MemoryStream(bytes))
        {
            localImage = Image.FromStream(ImageStream);
        }

        localImage = ResizeImage(localImage);

        using (MemoryStream ImageStreamOut = new MemoryStream())
        {
            localImage.Save(ImageStreamOut, ImageFormat.Jpeg);
            ImageBytes = ImageStreamOut.ToArray();
        }

    }
Dan Williams
Reproducing arbiter's comment: the ResizeImage should be inside the ImageStream using block, since calls to localImage could require access to the ImageStream before it is disposed, and you should dispose the (presumably new?) localImage returned by ResizeImage too.
Douglas