Using C#, is there a better way to convert a Windows Bitmap to a byte[] than saving to a temporary file and reading the result using a FileStream?
10 Answers
There are a couple ways.
ImageConverter
public static byte[] ImageToByte(Image img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
This one is convenient because it doesn't require a lot of code.
Memory Stream
public static byte[] ImageToByte2(Image img)
{
using (var stream = new MemoryStream())
{
img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
return stream.ToArray();
}
}
This one is equivalent to what you are doing, except the file is saved to memory instead of to disk. Although more code you have the option of ImageFormat and it can be easily modified between saving to memory or disk.
9 Comments
ImageConverter method will save the image as Png, resulting in HUGE files.ImageConverter isn't .net standard you might use MemoryStreamA MemoryStream can be helpful for this. You could put it in an extension method:
public static class ImageExtensions
{
public static byte[] ToByteArray(this Image image, ImageFormat format)
{
using(MemoryStream ms = new MemoryStream())
{
image.Save(ms, format);
return ms.ToArray();
}
}
}
You could just use it like:
var image = new Bitmap(10, 10);
// Draw your image
byte[] arr = image.ToByteArray(ImageFormat.Bmp);
I partially disagree with prestomanifto's answer in regards to the ImageConverter. Do not use ImageConverter. There's nothing technically wrong with it, but simply the fact that it uses boxing/unboxing from object tells me it's code from the old dark places of the .NET framework and its not ideal to use with image processing (it's overkill for converting to a byte[] at least), especially when you consider the following.
I took a look at the ImageConverter code used by the .Net framework, and internally it uses code almost identical to the one I provided above. It creates a new MemoryStream, saves the Bitmap in whatever format it was in when you provided it, and returns the array. Skip the extra overhead of creating an ImageConverter class by using MemoryStream
9 Comments
You can also just Marshal.Copy the bitmap data. No intermediary memorystream etc. and a fast memory copy. This should work on both 24-bit and 32-bit bitmaps.
public static byte[] BitmapToByteArray(Bitmap bitmap)
{
BitmapData bmpdata = null;
try
{
bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
int numbytes = bmpdata.Stride * bitmap.Height;
byte[] bytedata = new byte[numbytes];
IntPtr ptr = bmpdata.Scan0;
Marshal.Copy(ptr, bytedata, 0, numbytes);
return bytedata;
}
finally
{
if (bmpdata != null)
bitmap.UnlockBits(bmpdata);
}
}
.
14 Comments
Save the Image to a MemoryStream and then grab the byte array.
http://msdn.microsoft.com/en-us/library/ms142148.aspx
Byte[] data;
using (var memoryStream = new MemoryStream())
{
image.Save(memoryStream, ImageFormat.Bmp);
data = memoryStream.ToArray();
}
5 Comments
System.Drawing.Image (see: learn.microsoft.com/en-us/dotnet/api/… )System.Drawing.Image does not exist. So .. no, doesn't work :(using (var ms = new MemoryStream(previewBinary)) bitmap = (Bitmap)Image.FromStream(ms);Use a MemoryStream instead of a FileStream, like this:
MemoryStream ms = new MemoryStream();
bmp.Save (ms, ImageFormat.Jpeg);
byte[] bmpBytes = ms.ToArray();
5 Comments
ToArray, not GetBuffer.Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the MemoryStream object, the length of the buffer returned from GetBuffer is 256, not 4, with 252 bytes unused. To obtain only the data in the buffer, use the ToArray method. So now the byte array from GetBuffer will return the image plus unused bytes, which will probably result in a corrupt image.More simple:
return (byte[])System.ComponentModel.TypeDescriptor.GetConverter(pImagen).ConvertTo(pImagen, typeof(byte[]))
1 Comment
Try the following:
MemoryStream stream = new MemoryStream();
Bitmap bitmap = new Bitmap();
bitmap.Save(stream, ImageFormat.Jpeg);
byte[] byteArray = stream.GetBuffer();
Make sure you are using:
System.Drawing & using System.Drawing.Imaging;
2 Comments
Very simple use this just in one line:
byte[] imgdata = File.ReadAllBytes(@"C:\download.png");