views:

851

answers:

3

I'm trying to create an image object with a byte array as its source. What am I doing wrong?

An exception is thrown when I try to initialize the image object with an array of bytes as source data. The exception is shown in my code, below.

public class MyClass
{
    publuc System.Windows.Media.Imaging.BitmapImage InstanceImage { get; set; }

    public void GetImage()
    {
        // Retrieves a list of custom "Item" objects that contain byte arrays.
        // ScvClnt is our service client. The PollQueue method is designed to return information to us.
        lstQueue = SvcClnt.PollQueue(1);

        // This condition always evaluates as True, since we requested exactly 1 "Item" from the service client.
        if (lstQueue.Count == 1)
        {
            // lstQueue[0].InstanceImage is a byte array containing the data from an image file.
            // I have confirmed that it is a valid TIFF image file, by writing it to disk and opening it in MSPaint.
            if (lstQueue[0].InstanceImage != null)
            {
                // This condition is also True, since the image is just under 3KB.
                if (lstQueue[0].InstanceImage.Length > 0)
                {
                    this.InstanceImage = new System.Windows.Media.Imaging.BitmapImage();
                    this.InstanceImage.BeginInit();
                    this.InstanceImage.StreamSource = new System.IO.MemoryStream(lstQueue[0].InstanceImage);
                    InstanceImage.EndInit();
                    // The call to EndInit throws a NullReferenceException.
                    // {"Object reference not set to an instance of an object."}
                    // I have confirmed that this.InstanceImage and this.InstanceImage.StreamSource are not null at this point.
                    // They are successfully assigned in the lines of code above.
                } else InstanceImage = null;
            } else InstanceImage = null;
        } else InstanceImage = null;
    }
}

I have no idea what on Earth could possibly be going wrong.
Any advice would be much appreciated.

+3  A: 

I'm not sure I'm following what you're trying to do with your class at first glance, but to address the original question, give this a shot:

    public static Image ConvertByteArrayToImage(byte[] byteArrayIn)
    {
        MemoryStream ms = new MemoryStream(byteArrayIn);
        Image returnImage = Image.FromStream(ms);
        return returnImage;
    }
routeNpingme
Interesting .... Lemme give this a shot.
Giffyguy
I believe that this is a solution for .NET 2.0 or the like. I am working in .NET 3.5 using WPF. Therefore I'm not using System.Drawing
Giffyguy
+1  A: 

This MSDN forum post uses this example as a solution.

using (MemoryStream stream = new MemoryStream(abyteArray0))
{
    image.Source = BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}

//The field image should be of type System.Windows.Controls.Image.

I used the BitmapFrame.Create method that takes only the stream as a parameter, and it worked like a charm.

Giffyguy
A: 

I am trying to rotate an image and it is sent to the function as a BitmapFrame. I found a way to rotate it if it's an Image type. So I found this entry about converting a BitmapFrame to an Image type. For some reason it's still not working. here's the function.

[Cmdlet(VerbsData.ConvertTo, "Rotate")]
public class RotateCmdlet : PSCmdlet
{
    private BitmapFrame[] bFrame, outFrame;
    private BitmapSource src;
    private double pixelsize;
    private int degrees;
    private byte[] pixels, outPixels;

    [Parameter(ValueFromPipeline = true,
        ValueFromPipelineByPropertyName = true), ValidateNotNullOrEmpty]
    public BitmapFrame[] Bitmap
    {
        get
        {
            return bFrame;
        }
        set
        {
            bFrame = value;
        }
    }

    [Parameter(Position = 0), ValidateNotNullOrEmpty]
    public int Degrees
    {
        get
        {
            return degrees;
        }
        set
        {
            degrees = value;
        }
    }

    protected override void ProcessRecord()
    {
        base.ProcessRecord();
        Console.Write("Rotating the image {0} degrees...\n\n", degrees);
        outFrame = new BitmapFrame[bFrame.Length];
        for (int c = 0; c < bFrame.Length; c++)
        {
            Image image;

            pixelsize = bFrame[c].PixelWidth * bFrame[c].PixelHeight;
            pixels = new byte[(int)pixelsize];
            outPixels = new byte[(int)pixelsize];
            bFrame[c].CopyPixels(pixels, (int)(bFrame[c].Width * (bFrame[c].Format.BitsPerPixel / 8.0)), 0);

            Stream strm = new MemoryStream(pixels);
            image = Image.FromStream(strm);

            var newBitmap = new Bitmap((int)bFrame[c].PixelWidth, (int)bFrame[c].PixelHeight);
            var graphics = Graphics.FromImage(newBitmap);
            graphics.TranslateTransform((float)bFrame[c].PixelWidth / 2, (float)bFrame[c].PixelHeight / 2);
            graphics.RotateTransform(degrees);
            graphics.TranslateTransform(-(float)bFrame[c].PixelWidth / 2, -(float)bFrame[c].PixelHeight / 2);
            graphics.DrawImage(image, new System.Drawing.Point(0, 0));

            for (int i = 0; i < pixelsize; i++)
            {
                outPixels[i] = pixels[i];
            }

            src = BitmapSource.Create(bFrame[c].PixelWidth, bFrame[c].PixelHeight, bFrame[c].DpiX, bFrame[c].DpiY,
                bFrame[c].Format, bFrame[c].Palette, outPixels, (int)(bFrame[c].Width * (bFrame[c].Format.BitsPerPixel / 8)));
            outFrame[c] = BitmapFrame.Create(src);
        }
        WriteObject(outFrame);
    }
}
dabonz413
This has been moved to its own question, which can be found here: http://stackoverflow.com/questions/1290158/
Giffyguy
thanks. I thought of that after I posted this (minus the link) and made my own thread. if you could help with this problem, that would be great!
dabonz413