Question

I make a webrequest to receive a large jpeg as a byte array. This in turn can be converted to a memory stream. I need to get this data into a bitmapdata so that I can marshall copy it to a byte array again. Am i right in assuming that a byte array returned from a memory stream is not the same as a byte array returned from a marshall copy of bitmapdata to a byte array?

I do not want to write the memory stream out to an image as it will return a out of memory error due to its size AND the fact I am using compact cf C# 2.

this is my call to the server..

HttpWebRequest _request = (HttpWebRequest)WebRequest.Create("A url/00249.jpg");
                _request.Method = "GET";
                _request.Timeout = 5000;
                _request.ReadWriteTimeout = 20000;
                byte[] _buffer;
                int _blockLength = 1024;
                int _bytesRead = 0;
                MemoryStream _ms = new MemoryStream();
                using (Stream _response = ((HttpWebResponse)_request.GetResponse()).GetResponseStream())
                {
                    do
                    {
                        _buffer = new byte[_blockLength];
                        _bytesRead = _response.Read(_buffer, 0, _blockLength);
                        _ms.Write(_buffer, 0, _bytesRead);
                    } while (_bytesRead > 0);
                }

This is my code to read a byte array from a bitmapdata.

 Bitmap Sprite = new Bitmap(_file);
        Bitmapdata RawOriginal = Sprite.LockBits(new Rectangle(0, 0, Sprite.Width, Sprite.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
        int origByteCount = RawOriginal.Stride * RawOriginal.Height;
        SpriteBytes = new Byte[origByteCount];
        System.Runtime.InteropServices.Marshal.Copy(RawOriginal.Scan0, SpriteBytes, 0, origByteCount);
        Sprite.UnlockBits(RawOriginal);

Note: I do not want to use this:

Bitmap Sprite = new Bitmap(_file);

I want to go from:

MemoryStream _ms = new MemoryStream();

to

System.Runtime.InteropServices.Marshal.Copy(RawOriginal.Scan0, SpriteBytes, 0, origByteCount);

using what ever conversions are required without writing to a bitmap.

Was it helpful?

Solution

What you're asking is going to be difficult. The data you're receiving from the response object is a full jpeg image, which has a header and then a bunch of compressed data bytes. The byte array addressed by Scan0 is uncompressed and quite possibly includes some padding bytes at the end of each scan line.

Most importantly, you definitely cannot use Marshal.Copy to copy the received bytes to Scan0.

To do what you're asking will require that you parse the header of the jpeg that you receive and uncompress the image bits directly to Scan0, padding each scan line as appropriate. There is nothing in the .NET Framework that will do that for you.

The accepted answer to this question has a link to a library that might help you out.

Even if that works, I'm not certain it will help you out. If calling the BitMap constructor to create the image causes you to run out of memory, it's almost certain that this roundabout method will, as well.

Is the problem that you have so many sprites that you can't keep them all in memory, uncompressed? If so, you'll probably have to find some other way to solve your problem.

By the way, you can save yourself a lot of trouble by changing your code that reads the image to:

    MemoryStream _ms = new MemoryStream();
    using (Stream _response = ((HttpWebResponse)_request.GetResponse()).GetResponseStream())
    {
        _response.CopyTo(_ms);
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top