Convert a bitmap into a byte array - c#

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?

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.
Source: http://www.vcskicks.com/image-to-byte.php

A 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

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);
}
}
.

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();
}

Use a MemoryStream instead of a FileStream, like this:
MemoryStream ms = new MemoryStream();
bmp.Save (ms, ImageFormat.Jpeg);
byte[] bmpBytes = ms.ToArray();

More simple:
return (byte[])System.ComponentModel.TypeDescriptor.GetConverter(pImagen).ConvertTo(pImagen, typeof(byte[]))

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;

I believe you may simply do:
ImageConverter converter = new ImageConverter();
var bytes = (byte[])converter.ConvertTo(img, typeof(byte[]));

MemoryStream ms = new MemoryStream();
yourBitmap.Save(ms, ImageFormat.Bmp);
byte[] bitmapData = ms.ToArray();

Very simple use this just in one line:
byte[] imgdata = File.ReadAllBytes(#"C:\download.png");

Related

how to convert an image into base64 in xamarin.android?

I have this code, it works very well in android studio but not in xamarin
bitmap.Compress() has different arguments in xamarin and i am confused how to convert image into base64 or binary in xamarin.android?
I am receving an error in the 3rd line:
( bitmap.Compress() has some invalid arguments).
Bitmap bitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.ace1);
ByteArrayOutputStream bao = new ByteArrayOutputStream();
bitmap.Compress(Bitmap.CompressFormat.Jpeg, 100,bao);
byte[] ba = bao.ToByteArray();
string bal = Base64.EncodeToString(ba, Base64.Default);
If you look at the documentation for Bitmap.Compress in Xamarin, you'll see that the last parameter is a Stream.
The equivalent of ByteArrayOutputStream in .NET is MemoryStream, so your code would be:
Bitmap bitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.ace1);
MemoryStream stream = new MemoryStream();
bitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, stream);
byte[] ba = stream.ToArray();
string bal = Base64.EncodeToString(ba, Base64Flags.Default);
(You could use Convert.ToBase64String instead of Base64.EncodeToString if you wanted, too.)
This is how I'm getting a Byte[] for my Bitmap object:
Byte[] imageArray = null;
Bitmap selectedProfilePic = this.GetProfilePicBitmap ();
if (selectedProfilePic != null) {
using (var ms = new System.IO.MemoryStream ()) {
selectedProfilePic.Compress (Bitmap.CompressFormat.Png, 0, ms);
imageArray = ms.ToArray ();
}
}
Hope this helps.

Convert BitmapImage to byte[]

I have problem with converting BitmapImage to byte[]. I tried a lot of solutions and nothing works, every time i get different errors.
For example i found nice solutions but it also doesn't work. What's wrong with it?
I'm using Windows Phone 8.1.
public static byte[] ImageToBytes(BitmapImage img)
{
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap btmMap = new WriteableBitmap(img);
System.Windows.Media.Imaging.Extensions.SaveJpeg(btmMap, ms, img.PixelWidth, img.PixelHeight, 0, 100);
img = null;
return ms.ToArray();
}
}
this was taken from here: Convert Bitmap Image to byte array (Windows phone 8)
There is no argument given that corresponds to the required formal
parameter 'pixelHeight' of 'WriteableBitmap.WriteableBitmap(int, int)'
The type or namespace name 'Extensions' does not exist in the
namespace 'System.Windows.Media.Imaging' (are you missing an assembly
reference?)
or if somebody has got another idea how to convert it, please post it. Thanks a lot for any help!
I also tried this: BitmapImage to byte[]
but there was problem with usings
'BitmapImage' is an ambiguous reference between 'System.Windows.Media.Imaging.BitmapImage' and 'Windows.UI.Xaml.Media.Imaging.BitmapImage'
so I used "BitmapEncoder" but it doesn't have method like Save and Frame.
I think that it can't be done on this platform. I change my project to Windows Phone Silverlight/8.0 and there is working everything.
public static BitmapImage BytesToImage(byte[] bytes)
{
BitmapImage bitmapImage = new BitmapImage();
try
{
using (MemoryStream ms = new MemoryStream(bytes))
{
bitmapImage.SetSource(ms);
return bitmapImage;
}
}
finally { bitmapImage = null; }
}
public static byte[] ImageToBytes(BitmapImage img)
{
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap btmMap = new WriteableBitmap(img);
System.Windows.Media.Imaging.Extensions.SaveJpeg(btmMap, ms, img.PixelWidth, img.PixelHeight, 0, 100);
img = null;
return ms.ToArray();
}
}
see the below link it might help
https://social.msdn.microsoft.com/Forums/en-US/713c0ed1-d979-43ef-8857-bbe0b35576a9/windows-8-how-to-convert-bitmapimage-into-byte?forum=winappswithcsharp
Have you tried
MemoryStream ms = new MemoryStream();
WriteableBitmap wb = new WriteableBitmap(myImage);
wb.SaveJpeg(ms, myImage.PixelWidth, myImage.PixelHeight, 0, 100);
byte[] imageBytes = ms.ToArray();
You can also use extension method here
public static class MyExtensions
{
public static Byte[] ByteFromImage(this System.Windows.Media.Imaging.BitmapImage imageSource)
{
Stream stream = imageSource.StreamSource;
Byte[] imagebyte = null;
if (stream != null && stream.Length > 0)
{
using (BinaryReader br = new BinaryReader(stream))
{
imagebyte = br.ReadBytes((Int32)stream.Length);
}
}
return imagebyte;
}
}
and then call
System.Windows.Media.Imaging.BitmapImage myImage = new System.Windows.Media.Imaging.BitmapImage();
byte[] imageBytes = myImage.ByteFromImage();
If you're going to do any transformation on the image, you'll want to use the appropriate image encoder, then do something like below. If you're working with a multi-frame image (eg TIF), you need to add the frames one at a time to the encoder or you'll only get the first frame of the image.
MemoryStream ms = null;
TiffBitmapEncoder enc = null
enc = new TiffBitmapEncoder();
enc.Compression = TiffCompressOption.Ccitt4;
enc.Frames.Add(BitmapFrame.Create(bmpImg));
using (ms = new MemoryStream())
{
enc.Save(ms);
}
return ms.ToArray();

Convert PNG byte array to JPEG byte array

I use the following code to convert a BitmapSource to a byte array representing a png:
/// <summary>
/// Converts BitmapSource to a PNG Bitmap.
/// </summary>
/// <param name="source">The source object to convert.</param>
/// <returns>byte array version of passed in object.</returns>
public static byte[] ToPngBytes(this BitmapSource source)
{
// Write the source to the bitmap using a stream.
using (MemoryStream outStream = new MemoryStream())
{
// Encode to Png format.
var enc = new Media.Imaging.PngBitmapEncoder();
enc.Frames.Add(Media.Imaging.BitmapFrame.Create(source));
enc.Save(outStream);
// Return image bytes.
return outStream.ToArray();
}
}
I'm looking to do the same operation but convert a byte array that's a Jpeg without having to create a BitmapSource first.
Signature should look like this:
public static byte[] ToPngBytes(this byte[] jpegBytes)
This code works but seems inefficient as I've to use a Writeable Bitmap to do this:
private WriteableBitmap colorBitmap;
private byte[] GetCompressedImage(byte[] imageData, System.Windows.Media.PixelFormat format, int width, int height, int bytesPerPixel = sizeof(Int32))
{
// Initialise the color bitmap converter.
if (colorBitmap == null)
colorBitmap = new WriteableBitmap(width, height, 96.0, 96.0, format, null);
// Write the pixels to the bitmap.
colorBitmap.WritePixels(new Int32Rect(0, 0, width, height), imageData, width * bytesPerPixel, 0);
// Memory stream used for encoding.
using (MemoryStream memoryStream = new MemoryStream())
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
// Add the frame to the encoder.
encoder.Frames.Add(BitmapFrame.Create(colorBitmap));
encoder.Save(memoryStream);
// Get the bytes.
return memoryStream.ToArray();
}
}
Below is a snippet of code to take a byte array of any format and convert it to a byte array with a JPG format:
byte[] jpgImageBytes = null;
using (var origImageStream = new MemoryStream(image))
using (var jpgImageStream = new MemoryStream())
{
var jpgImage = System.Drawing.Image.FromStream(origImageStream);
jpgImage.Save(jpgImageStream, System.Drawing.Imaging.ImageFormat.Jpeg);
jpgImageBytes = jpgImageStream.ToArray();
jpgImage.Dispose();
}
Bit Late for the answer but this should help others. In this solution it doesn't matter which type of image it is(as long as it's an image you can convert it to any type.
public static byte[] ConvertImageBytes(byte[] imageBytes, ImageFormat imageFormat)
{
byte[] byteArray = new byte[0];
FileStream stream = new FileStream("empty." + imageFormat, FileMode.Create);
using (MemoryStream ms = new MemoryStream(imageBytes))
{
stream.Write(byteArray, 0, byteArray.Length);
byte[] buffer = new byte[16 * 1024];
int read;
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
byteArray = ms.ToArray();
stream.Close();
ms.Close();
}
return byteArray;
}
Use it like as below
ConvertImageBytes(imageBytes, ImageFormat.Png);

convert binary to bitmap using memory stream

Hi I wanna convert binary array to bitmap and show image in a picturebox. I wrote the following code but I got exception that says that the parameter is not valid .
public static Bitmap ByteToImage(byte[] blob)
{
MemoryStream mStream = new MemoryStream();
byte[] pData = blob;
mStream.Write(pData, 0, Convert.ToInt32(pData.Length));
Bitmap bm = new Bitmap(mStream);
mStream.Dispose();
return bm;
}
It really depends on what is in blob. Is it a valid bitmap format (like PNG, BMP, GIF, etc?). If it is raw byte information about the pixels in the bitmap, you can not do it like that.
It may help to rewind the stream to the beginning using mStream.Seek(0, SeekOrigin.Begin) before the line Bitmap bm = new Bitmap(mStream);.
public static Bitmap ByteToImage(byte[] blob)
{
using (MemoryStream mStream = new MemoryStream())
{
mStream.Write(blob, 0, blob.Length);
mStream.Seek(0, SeekOrigin.Begin);
Bitmap bm = new Bitmap(mStream);
return bm;
}
}
Don't dispose of the MemoryStream. It now belongs to the image object and will be disposed when you dispose the image.
Also consider doing it like this
var ms = new MemoryStream(blob);
var img = Image.FromStream(ms);
.....
img.Dispose(); //once you are done with the image.
System.IO.MemoryStream mStrm = new System.IO.MemoryStream(your byte array);
Image im = Image.FromStream(mStrm);
im.Save("image.bmp");
Try this. If you still get any error or exception; please post your bytes which you are trying to convert to image. There should be problem in your image stream....

How to Convert system.windows.controls.image to byte[]

I need to convert System.Windows.Controls.Image to byte[].
How to do it ?
Assuming that you answer my query above that you are actually trying to convert an image into a byte array rather than an image control into a byte array here is the code to do so;
public byte[] imageToByteArray(System.Drawing.Image imageIn)
{
MemoryStream ms = new MemoryStream();
imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Gif);
return ms.ToArray();
}
In general, to convert an object to a byte array, you may want to use binary serialization. This will generate a memory stream from which you can extract a byte array.
You may start with this Question and Answer
System.Windows.Controls.Image img = new System.Windows.Controls.Image();
var uri = new Uri("pack://application:,,,/Images/myImage.jpg");
img.Source = new BitmapImage(uri);
byte[] arr;
using (MemoryStream ms = new MemoryStream())
{
var bmp = img.Source as BitmapImage;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
encoder.Save(ms);
arr = ms.ToArray();
}

Categories