Convert Image into ByteArray - c#

I know there already are plenty of post about this, but every solution I have tried so far failed. What I want is to get a Byte[] from an Image object.
What I have tried so far:
using (MemoryStream ms = new MemoryStream()){/*...*/} (GDI+ Exception)
Working on a copy of the image (ArgumentNullException (Encoder))
Follow the solution from Microsoft (ArgumentNullException (Encoder))
Use an ImageConverter (GDI+ Exception)
What I expect to have:
public static Byte[] BytesFromImage(Image img) {
Byte[] imgFile;
MemoryStream ms = new MemoryStream();
img.Save(ms, img.RawFormat);
imgfile = ms.ToArray();
return imgFile;
}
Everytime I get an error, it comes from img.save(ms, img.RawFormat);.
Maybe it is just me, but all of the solution that I've followed on StackOverflow gave me the same results: a GDI+ Error with such a great explanation.

Replace img.RawFormat with ImageFormat.Bmp
Example:
class Program
{
public static byte[] BytesFromImage(Image img)
{
Byte[] imgFile;
MemoryStream ms = new MemoryStream();
img.Save(ms, ImageFormat.Bmp);
imgFile = ms.ToArray();
return imgFile;
}
private static void Main(string[] args)
{
using (Image image = new Bitmap(100, 100))
{
byte[] imgArr = BytesFromImage(image);
Console.WriteLine("Image size is: {0}", imgArr.Length);
}
}

Related

Bitmap from Memstream of an SVG gives invalid parameter exception

The last line of the following code gives the error "Parameter is not valid", when the original image is an SVG:
var imageBytes = Convert.FromBase64String(imageBase64String);
var memStream = new MemoryStream(imageBytes);
//memStream.Seek(0, SeekOrigin.Begin);
var imageObject = new Bitmap(memStream);
Help please. Thanks.
EDIT: The image for example I am using is the image of the first formula in the following page right under the Theoremsection:
https://en.wikipedia.org/wiki/Green%27s_theorem
Can you try with 'using' for memorystream to handle garbage collection by itself?
var imageBytes = Convert.FromBase64String(imageBase64String);
Bitmap m = ByteToBitmap(imageBytes);
public static Bitmap ByteToBitmap(byte[] imageByte)
{
using (MemoryStream mStream = new MemoryStream())
{
mStream.Write(imageByte, 0, imageByte.Length); // this will stream dataand handle image length by itself
mStream.Seek(0, SeekOrigin.Begin);
Bitmap bm = new Bitmap(mStream);
return bm;
}
}
For SVG,
public static Bitmap ByteToBitmap(byte[] imageByte)
{
using (MemoryStream mStream = new MemoryStream(imageByte))
{
var s= SvgDocument.Open(mStream);
var bm= svgDocument.Draw();
return bm;
}
}

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

How to convert PictureBoxImage to byte array

How can I convert a PictureBox.Image to byte array to store in database directly ..
I tried the following code but they all give me the same error " a generic error occurred in GDI + "
public static byte[] ImageToByte(Image img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
public byte[] convertImageToByteArray(System.Drawing.Image image)
{
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
// or whatever output format you like
return ms.ToArray();
}
}
P.S I am running the program as Administrator too

Error" Parameter is not valid " while converting Bytes into Image

I am converting bytes into an image but I get an error
Parameter is not valid
I am pasting my code. Kindly check the code and suggested that was I am doing right or wrong.
Image arr1 = byteArrayToImage(Bytess);
This is the function.
public static Image byteArrayToImage(byte[] byteArrayIn)
{
if (null == byteArrayIn || byteArrayIn.Length == 0)
return null;
MemoryStream ms = new MemoryStream(byteArrayIn);
try
{
Process currentProcess1 = Process.GetCurrentProcess();
Image returnImage = Image.FromStream(ms);
return returnImage;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I applied many techniques and solutions but it did not work for me
Your answer would be appreciated.
Thanks
try this
public Image byteArrayToImage(byte[] byteArrayIn)
{
System.Drawing.ImageConverter converter = new System.Drawing.ImageConverter();
Image img = (Image)converter.ConvertFrom(byteArrayIn);
return img;
}
After trying many things I found a way which has a little bit more control.
In this example you can specify the pixel format and copy the bytes to a Bitmap.
byte[] buffer = GetImageBytes();
var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
var bitmap_data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(buffer, 0, bitmap_data.Scan0, buffer.Length);
bitmap.UnlockBits(bitmap_data);
var result = bitmap as Image;
The problem is because, you are bringing it incorrectly from database. Try changing your code like this:
while (registry.Read())
{
byte[] image = (byte[])registry["Image"];
}
In my case I got the error since my base64 string had wrong encoding before calling Image.FromStream.
This worked for me in the end:
byte[] bytes = System.Convert.FromBase64String(base64ImageString);
using (MemoryStream ms = new MemoryStream(bytes))
{
var image = Image.FromStream(ms);
image.Save(filePath, System.Drawing.Imaging.ImageFormat.Png);
}
cmd.CommandText="SELECT * FROM `form_backimg` WHERE ACTIVE=1";
MySqlDataReader reader6= cmd.ExecuteReader();
if(reader6.Read())
{
code4 = (byte[])reader6["BACK_IMG"]; //BLOB FIELD NAME BACK_IMG
}
reader6.Close();
MemoryStream stream = new MemoryStream(code4); //code4 is a public byte[] defined on top
pictureBox3.Image = Image.FromStream(stream);
try this,
public Image byteArrayToImage(byte[] byteArrayIn)
{
Image returnImage = null;
using (MemoryStream ms = new MemoryStream(byteArrayIn))
{
returnImage = Image.FromStream(ms);
}
return returnImage;
}

Convert a bitmap into a byte array

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");

Categories