How to convert image to byte array [duplicate] - c#

This question already has answers here:
Convert System.Windows.Media.ImageSource to ByteArray
(1 answer)
Convert byte array to image in wpf
(3 answers)
convert array of bytes to bitmapimage
(2 answers)
Closed 7 months ago.
Can anybody suggest how I can convert an image to a byte array and vice versa?
I'm developing a WPF application and using a stream reader.

Sample code to change an image into a byte array
public byte[] ImageToByteArray(System.Drawing.Image imageIn)
{
using (var ms = new MemoryStream())
{
imageIn.Save(ms,imageIn.RawFormat);
return ms.ToArray();
}
}
C# Image to Byte Array and Byte Array to Image Converter Class

For Converting an Image object to byte[] you can do as follows:
public static byte[] converterDemo(Image x)
{
ImageConverter _imageConverter = new ImageConverter();
byte[] xByte = (byte[])_imageConverter.ConvertTo(x, typeof(byte[]));
return xByte;
}

Another way to get Byte array from image path is
byte[] imgdata = System.IO.File.ReadAllBytes(HttpContext.Current.Server.MapPath(path));

Here's what I'm currently using. Some of the other techniques I've tried have been non-optimal because they changed the bit depth of the pixels (24-bit vs. 32-bit) or ignored the image's resolution (dpi).
// ImageConverter object used to convert byte arrays containing JPEG or PNG file images into
// Bitmap objects. This is static and only gets instantiated once.
private static readonly ImageConverter _imageConverter = new ImageConverter();
Image to byte array:
/// <summary>
/// Method to "convert" an Image object into a byte array, formatted in PNG file format, which
/// provides lossless compression. This can be used together with the GetImageFromByteArray()
/// method to provide a kind of serialization / deserialization.
/// </summary>
/// <param name="theImage">Image object, must be convertable to PNG format</param>
/// <returns>byte array image of a PNG file containing the image</returns>
public static byte[] CopyImageToByteArray(Image theImage)
{
using (MemoryStream memoryStream = new MemoryStream())
{
theImage.Save(memoryStream, ImageFormat.Png);
return memoryStream.ToArray();
}
}
Byte array to Image:
/// <summary>
/// Method that uses the ImageConverter object in .Net Framework to convert a byte array,
/// presumably containing a JPEG or PNG file image, into a Bitmap object, which can also be
/// used as an Image object.
/// </summary>
/// <param name="byteArray">byte array containing JPEG or PNG file image or similar</param>
/// <returns>Bitmap object if it works, else exception is thrown</returns>
public static Bitmap GetImageFromByteArray(byte[] byteArray)
{
Bitmap bm = (Bitmap)_imageConverter.ConvertFrom(byteArray);
if (bm != null && (bm.HorizontalResolution != (int)bm.HorizontalResolution ||
bm.VerticalResolution != (int)bm.VerticalResolution))
{
// Correct a strange glitch that has been observed in the test program when converting
// from a PNG file image created by CopyImageToByteArray() - the dpi value "drifts"
// slightly away from the nominal integer value
bm.SetResolution((int)(bm.HorizontalResolution + 0.5f),
(int)(bm.VerticalResolution + 0.5f));
}
return bm;
}
Edit: To get the Image from a jpg or png file you should read the file into a byte array using File.ReadAllBytes():
Bitmap newBitmap = GetImageFromByteArray(File.ReadAllBytes(fileName));
This avoids problems related to Bitmap wanting its source stream to be kept open, and some suggested workarounds to that problem that result in the source file being kept locked.

try this:
public byte[] imageToByteArray(System.Drawing.Image imageIn)
{
MemoryStream ms = new MemoryStream();
imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Gif);
return ms.ToArray();
}
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}

You can use File.ReadAllBytes() method to read any file into byte array. To write byte array into file, just use File.WriteAllBytes() method.
Hope this helps.
You can find more information and sample code here.

If you don't reference the imageBytes to carry bytes in the stream, the method won't return anything. Make sure you reference imageBytes = m.ToArray();
public static byte[] SerializeImage() {
MemoryStream m;
string PicPath = pathToImage";
byte[] imageBytes;
using (Image image = Image.FromFile(PicPath)) {
using ( m = new MemoryStream()) {
image.Save(m, image.RawFormat);
imageBytes = new byte[m.Length];
//Very Important
imageBytes = m.ToArray();
}//end using
}//end using
return imageBytes;
}//SerializeImage

Do you only want the pixels or the whole image (including headers) as an byte array?
For pixels: Use the CopyPixels method on Bitmap. Something like:
var bitmap = new BitmapImage(uri);
//Pixel array
byte[] pixels = new byte[width * height * 4]; //account for stride if necessary and whether the image is 32 bit, 16 bit etc.
bitmap.CopyPixels(..size, pixels, fullStride, 0);

Code:
using System.IO;
byte[] img = File.ReadAllBytes(openFileDialog1.FileName);

This is Code for converting the image of any type(for example PNG, JPG, JPEG) to byte array
public static byte[] imageConversion(string imageName){
//Initialize a file stream to read the image file
FileStream fs = new FileStream(imageName, FileMode.Open, FileAccess.Read);
//Initialize a byte array with size of stream
byte[] imgByteArr = new byte[fs.Length];
//Read data from the file stream and put into the byte array
fs.Read(imgByteArr, 0, Convert.ToInt32(fs.Length));
//Close a file stream
fs.Close();
return imageByteArr
}

To be convert the image to byte array.The code is give below.
public byte[] ImageToByteArray(System.Drawing.Image images)
{
using (var _memorystream = new MemoryStream())
{
images.Save(_memorystream ,images.RawFormat);
return _memorystream .ToArray();
}
}
To be convert the Byte array to Image.The code is given below.The code is handle A Generic error occurred in GDI+ in Image Save.
public void SaveImage(string base64String, string filepath)
{
// image convert to base64string is base64String
//File path is which path to save the image.
var bytess = Convert.FromBase64String(base64String);
using (var imageFile = new FileStream(filepath, FileMode.Create))
{
imageFile.Write(bytess, 0, bytess.Length);
imageFile.Flush();
}
}

This code retrieves first 100 rows from table in SQLSERVER 2012 and saves a picture per row as a file on local disk
public void SavePicture()
{
SqlConnection con = new SqlConnection("Data Source=localhost;Integrated security=true;database=databasename");
SqlDataAdapter da = new SqlDataAdapter("select top 100 [Name] ,[Picture] From tablename", con);
SqlCommandBuilder MyCB = new SqlCommandBuilder(da);
DataSet ds = new DataSet("tablename");
byte[] MyData = new byte[0];
da.Fill(ds, "tablename");
DataTable table = ds.Tables["tablename"];
for (int i = 0; i < table.Rows.Count;i++ )
{
DataRow myRow;
myRow = ds.Tables["tablename"].Rows[i];
MyData = (byte[])myRow["Picture"];
int ArraySize = new int();
ArraySize = MyData.GetUpperBound(0);
FileStream fs = new FileStream(#"C:\NewFolder\" + myRow["Name"].ToString() + ".jpg", FileMode.OpenOrCreate, FileAccess.Write);
fs.Write(MyData, 0, ArraySize);
fs.Close();
}
}
please note: Directory with NewFolder name should exist in C:\

Related

C# Image to base64

I have a base64 image and i have to convert it into Image. I am doing this using this code:
public static Image ConvertBase64StringToImage(string imageBase64String)
{
var imageBytes = Convert.FromBase64String(imageBase64String);
var imageStream = new MemoryStream(imageBytes, 0, imageBytes.Length);
imageStream.Write(imageBytes, 0, imageBytes.Length);
var image = Image.FromStream(imageStream, true);
return image;
}
Then i have to convert this Image into base64 again. Im using this code:
public static string ConvertImageToBase64String(Image image)
{
var imageStream = new MemoryStream();
image.Save(imageStream, ImageFormat.Png);
imageStream.Position = 0;
var imageBytes = imageStream.ToArray();
return Convert.ToBase64String(imageBytes);
}
After converting the original base64Image to image and again to base64, it loses quality.The Original base64 image is 1676 in length and after conversion it has 1660 in length.
I need the same image after conversion because i have to compare it. Any ideas how to do it without losing quality?
According to this page although PNG files are lossless, you can specify how much file compression to use when storing. IMO, as long as the Image comes out the same (you can compare them using some sort of MD5 tool), it doesn't matter if the size of the file is different when you save it, as the actual image is still the same as the original.
This is how to convert and compare your images, if the result from CompareImages is zero, it means that they are equal or very similar.
static void Main(string[] args)
{
Image img = new Bitmap("Koala.jpg");
string img64Bit = ConvertImageToBase64String(img);
Image newImg = ConvertBase64StringToImage(img64Bit);
newImg.Save("KoalaCopy.jpg");
Console.WriteLine(CompareImages(img, newImg));
Console.ReadLine();
}
public static string ConvertImageToBase64String(Image image)
{
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, image.RawFormat);
return Convert.ToBase64String(ms.ToArray());
}
}
public static Image ConvertBase64StringToImage(string image64Bit)
{
byte[] imageBytes = Convert.FromBase64String(image64Bit);
return new Bitmap(new MemoryStream(imageBytes));
}
public static int CompareImages(Image i1, Image i2)
{
string img1 = ConvertImageToBase64String(i1);
string img2 = ConvertImageToBase64String(i2);
return String.Compare(img1, img2);
}

Convert bitmapimage into byte array

I am trying to convert bitmap Image to Byte array. I have select all the image by using MediaLibrary class and added it into a list of bitmap images. Here is my code
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!store.DirectoryExists("ImagesZipFolder"))
{
store.CreateDirectory("ImagesZipFolder");
for (int i = 0; i < imgname.Count(); i++)
{
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(#"ImagesZipFolder\" + imgname[i], System.IO.FileMode.CreateNew, store))
{
byte[] bytes = null;
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap wBitmap = new WriteableBitmap(ImgCollection[i]);
wBitmap.SaveJpeg(ms, wBitmap.PixelWidth, wBitmap.PixelHeight, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
bytes = ms.GetBuffer();
stream.Write(bytes, 0, bytes.Length);
}
// byte[] bytes = Encoding.UTF8.GetBytes(imgname[i]);//new byte[ImgCollection[i].PixelWidth * ImgCollection[i].PixelHeight * 4];
// stream.Write(bytes, 0, bytes.Length);
}
}
}
else {
directory = true;
}
}
Basically what I am trying to do is, selecting all images or photo from device and create a zip file of that images. I was successful in creating a zip file of images. When I extract that file there is some images, but the problem is when I double click on image, I can't see that image. I think the problem is in reading the bytes of image. I am not getting what's wrong? Is my code is correct ?
Perhaps you can try the below. I know this code maintains the image, so if you have no luck using this, you may have a different issue.
// Convert the new image to a byte[]
ImageConverter converter = new ImageConverter();
byte[] newBA = (byte[])converter.ConvertTo(newImage, typeof(byte[]));
The ImageConverter is of the System.Drawing namespace.
Update:
http://msdn.microsoft.com/en-GB/library/system.windows.media.imagesourceconverter.convertto.aspx
You should be able to use this in place of the System.Drawing type I suggested.
There is no need to save the WriteableBitmap to a MemoryStream and then copy it to an IsolatedStorageFileStream. Just save the bitmap directly to the IsolatedStorageFileStream.
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(#"ImagesZipFolder\" + imgname[i], System.IO.FileMode.CreateNew, store))
{
WriteableBitmap wBitmap = new WriteableBitmap(ImgCollection[i]);
wBitmap.SaveJpeg(stream, wBitmap.PixelWidth, wBitmap.PixelHeight, 0, 100);
}
This will allow you to save on memory as well. If you really want to save memory, you could reuse the WriteableBitmap.

Converting image to base64

I have the following code to convert image to base64:
private void btnSave_Click(object sender, RoutedEventArgs e)
{
StreamResourceInfo sri = null;
Uri uri = new Uri("Checked.png", UriKind.Relative);
sri = Application.GetResourceStream(uri);
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(sri.Stream);
WriteableBitmap wb = new WriteableBitmap(bitmap);
MemoryStream ms = new MemoryStream();
wb.SaveJpeg(ms, bitmap.PixelWidth, bitmap.PixelHeight, 0, 100);
byte[] imageBytes = ms.ToArray();
base64 = System.Convert.ToBase64String(imageBytes);
}
And the following code to get Bitmap image form base 64:
public static BitmapImage base64image(string base64string)
{
byte[] fileBytes = Convert.FromBase64String(base64string);
using (MemoryStream ms = new MemoryStream(fileBytes, 0, fileBytes.Length))
{
ms.Write(fileBytes, 0, fileBytes.Length);
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(ms);
return bitmapImage;
}
}
So when i convert and deconvert it is blank.
I know that deconverter works, because, when i give him exact string:
string base64="iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAQAAABLCVATAAACH0lEQVR42q3WoZKrMBQGYGRkIpHEoY9DMrh1nUGtzxPcGV7gCsTaK3iBCqa2ipmrVqLrWrmytjL3nBwoEGD30ja/6JaSj/wp3SEIXjpUoB+Oeg0zpoR+NsyoDVOgi39cbYHAy4MQTc0wOYZepxRBUkn9UxxEiNnXxyYwd6w/438hSddHJilv1tqv664Shle1DeJaJihPV9uNQ+NWBRK2QVSr+GjtaFzOIpdjKFShnoY+Gv0N0u0OVLexY48NQ+68JchdpQu/o1piVMu6faJdwjNWIAYyl55bqGUtbndO53TzCIpUpCkdlEm+V3J3Ir8r3uops2+FkTmvx832IGJwN97xS/5Ti0LQ/WLwtbxMal2ueAwvc2c8CAgSJip5U4+tKHECMlUzq2UcA9EyROuJi6/71dtzWAfVcq0Jw1CsYh13kDDteVoirE+zWtLVinQ8ZAS5YlVlvRHWfi3pakUQL0OOwmp/W/vN6Gt5zBIkzEezxnCtMJsxDIECTYmhp3bej4HHzaalNMyAnzE0UBKp6Z1Do2pwd3JkAH6CxlTs/bZOZ661yMwhohDLQqREMWz8UAvWoUQleggehG5dSPUbv28GJlnKHGJsqPi7vuG/MGTyCGslOtkCOayrGOa/indajdudb6FUpXoepgiLHIIMriddyzrkMBhGAqlOH4U2hKCT2j0NdU8jFbzpZ3LQlh9srPqEQ1Y9lEP2CVa99KHvH8mnrGGdl9V9AAAAAElFTkSuQmCC";
Which is my Checked.png converted in online converter. It decompreses perfectly.
And this is my base64, which i get by converting:
"/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAkACQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+AXyv978v/rUeV7N+X/1q0FhyFxnlc9vT6d+APcgV2HiL4cePvCGheCvFHizwR4w8L+GfiVo9/wCIvhz4i8ReGda0TQfH3h/S9av/AA3qeueCtX1OxtdP8V6Pp3iLS9U0G+1PQbm/srTWtNv9LnnjvrO4gjAOO0rRtS1zUtP0bRtPv9W1fVr600zS9K0y0nv9S1PUr+eO1sdP0+xtY5bq8vby6mitrW1t4pJ7ieWOGGN5HVS/WND1Xw9qup6Frumajout6JqN7pGs6Nq1lcadqukatptzLZajpmp6deRQ3dhqFhewTWl7ZXUMVza3MMsE8ccqMg/tk/4NKv8Agjy3xm+JkH/BTj9oDwss3wm+DXiC70v9l3QNZtEktfHvxp0Sd7XVvin9mucpc+Hfg9cB7PwxdC1lhu/irIdR0/UbPVfhdeW13yf/AAeM/Fj9iTXf2pvhp8IPg/8ACjwRJ+2H4N02PxJ+1F8dPCpbStUi0bWdGhX4e/CLxnY6TPBpHjPxmdHms/GWpeIfEthc+JPCXhj/AIQTw9o+tyafrms6PpYB/Fiy7Tjn8aKluV2yY/2RRQB7r8CtS+E3h34wfCvxD8efBvib4hfBXRfHnhLVfir4E8G+ILfwv4o8YeALLWLO58UeHtD1+5t7mLTNQ1TSUurSKY/ZJZPN8i31XRLiWLWLL/W48Q/Bf/gmX/wXm/4Jg6V8PfgkPhtqfwYT4ey+EfgFrOleDorLxX+xt8SNA8Jnwz4Ot4fh9pmseE9d8E6x8M2t9Jt9T+HEOveHvD/jvwbY2+l2uq6n4D8Q6Vrd3/kEQxfuYiMcxp3PdB+Fff8A/wAE7v8AgpB+1H/wTJ+Omn/Gv9mzxpLp9veT6ba/Ez4Wa1NdXXwy+L/hayunmPhzxx4eS4ijnmhjuL1dC8UaebXxX4Unvry58P6tZi+1GG7AP9Q3/gpJ+2p+zz/wQi/4JraUnww8MeHNE1Lwp4PsfgV+x58FbcKIvEPju20OSDR9R1i3iaG81Dw34RiSbx98U/Ed3PBe69Ik1nc6w3jPxro7ah/kLfEnx946+L/xB8b/ABV+JviXVvG3xF+I/ivXvG/jrxdrlws+r+JfFfibU7nV9c1nUZQsStdX+o3dxcyCKKG3jMnlW0ENvHFGv6ff8Fgf+CqPxQ/4K0ftQQfHDxdoEnw7+HHgrwxZeCfgx8HY/EDeI7H4f6AUhv8AxNfXeqrY6Tba34q8X+JjcalrmvpoumS3OmWnhnw+8Mtj4YsGH5ReT9PzNAHF6guy4K4wdi5HXrmip9YXbesP+mcfr6UUAdHb+NTFbwQ3Hhnw5qE0MUcT310fEUd1ciKNI0e4Fh4hsrRptqDzJY7WOSeQvNO0szvI0v8AwnEX/QneFf8Av74t/wDmroooAP8AhOIv+hO8K/8Af3xb/wDNXSjxzECD/wAIb4UODnBl8XYPsceLAcH2IPoRRRQByWp6g+p3kl21taWm8KqW1lE0UEUaDaiKZZJriUgcGa6uLi4fjzJnwMFFFAH/2Q=="
My problem is that string which i get as base64 from my code - is incorrect *What i did wrong?*
What about trying:
public static BitmapImage base64image(string base64string)
{
byte[] fileBytes = Convert.FromBase64String(base64string);
using (MemoryStream ms = new MemoryStream(fileBytes))
{
Image streamImage = Image.FromStream(ms);
context.Response.ContentType = "image/jpeg";
streamImage.Save(context.Response.OutputStream, ImageFormat.Jpeg);
return streamImage;
}
}
I agree with Alexei that your code for reading the image in does look a little strange. I've recently written some code for a similar task that I was doing which might point you in the right direction:
string fileContent = null;
/* Check the file actually has some content to display to the user */
if (uploadFile != null && uploadFile.ContentLength > 0)
{
byte[] fileBytes = new byte[uploadFile.ContentLength];
int byteCount = uploadFile.InputStream.Read(fileBytes, 0, (int)uploadFile.ContentLength);
if (byteCount > 0)
{
fileContent = CreateBase64Image(fileBytes);
}
}
private string CreateBase64Image(byte[] fileBytes)
{
Image streamImage;
/* Ensure we've streamed the document out correctly before we commit to the conversion */
using (MemoryStream ms = new MemoryStream(fileBytes))
{
/* Create a new image, saved as a scaled version of the original */
streamImage = ScaleImage(Image.FromStream(ms));
}
using (MemoryStream ms = new MemoryStream())
{
/* Convert this image back to a base64 string */
streamImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return Convert.ToBase64String(ms.ToArray());
}
}
not an answer: more of a long comment ... OP states that decoding code works perfectly fine, also it looks suspicios. Also code assumed to be verified to work on PNG images, but saving code explicitly produces valid JPG with SaveJpeg call...
Your code that creates stream for reading looks strange - you create stream over existing byte array, than write the same bytes into that stream, and that pass that stream without seeking back to 0 to some method.
Potential fix (assuming BitampImage can accept JPG stream):
don't call Write at all as stream already have the bytes you want
set ms.Position = 0 after writing to the stream.
Note: I'm not sure if it is OK to dispose stream that is a source for BitmapImage, you may need to remove using too.

How to put image in a picture box from a byte[] in C#

I've a byte array which contains an image binary data in bitmap format. How do I display it using the PictureBox control in C#?
I went thru a couple of posts listed below but not sure if I need to convert the byte array into something else before sending it to a picturebox. I'd appreciate your help. Thanks!
How to put image in a picture box from Bitmap
Load Picturebox Image From Memory?
This function converts byte array into Bitmap which can be use to set the Image Property of the picturebox.
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, false);
mStream.Dispose();
return bm;
}
Sample usage:
pictureBox.Image = ByteToImage(byteArr); // byteArr holds byte array value
byte[] imageSource = **byte array**;
Bitmap image;
using (MemoryStream stream = new MemoryStream(imageSource))
{
image = new Bitmap(stream);
}
pictureBox.Image = image;
using System.IO;
byte[] img = File.ReadAllBytes(openFileDialog1.FileName);
MemoryStream ms = new MemoryStream(img);
pictureBox1.Image = Image.FromStream(ms);
or you can access like this directly,
pictureBox1.Image = Image.FromFile(openFileDialog1.FileName);
You can also convert pictureBox image to byte array like this,
MemoryStream ms = new MemoryStream();
pictureBox1.Image.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] img = ms.ToArray();
The ImageConverter class in the System.Drawing namespace can do the conversion:
byte[] imageArray = **byte array**
ImageConverter converter = new ImageConverter();
pictureButton.Image = (Image)converter.ConvertFrom(imageArray);
If you want to use BinaryReader to convert then use like this,
FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
byte[] img = br.ReadBytes((int)fs.Length);
Try this for Converting Bitmap Images to array of bytes for jpeg pictures and png file types:
public byte[] UdfConvertPicToByte(Bitmap bitmapImages)
{
using (MemoryStream stream = new MemoryStream())
{
bitmapImages.Compress(Bitmap.CompressFormat.Png, 0, stream);
byte[] bitmapData = stream.ToArray();
bitmap.Compress(Bitmap.CompressFormat.Jpeg, 50, stream);
bitmapData = stream.ToArray();
return bitmapData;
}
}

Image.FromStream() method returns Invalid Argument exception

I am capturing images from a smart camera imager and receiving the byte array from the camera through socket programming (.NET application is the client, camera is the server).
The problem is that i get System.InvalidArgument exception at runtime.
private Image byteArrayToImage(byte[] byteArray)
{
if(byteArray != null)
{
MemoryStream ms = new MemoryStream(byteArray);
return Image.FromStream(ms, false, false);
/*last argument is supposed to turn Image data validation off*/
}
return null;
}
I have searched this problem in many forums and tried the suggestions given by many experts but nothing helped.
I dont think there is any problem with the byte array as such because When i feed the same byte array into my VC++ MFC client application, i get the image. But this doesn't somehow work in C#.NET.
Can anyone help me ?
P.S :
Other methods i've tried to accomplish the same task are:
1.
private Image byteArrayToImage(byte[] byteArray)
{
if(byteArray != null)
{
MemoryStream ms = new MemoryStream();
ms.Write(byteArray, 0, byteArray.Length);
ms.Position = 0;
return Image.FromStream(ms, false, false);
}
return null;
}
2.
private Image byteArrayToImage(byte[] byteArray)
{
if(byteArray != null)
{
TypeConverter tc = TypeDescriptor.GetConverter(typeof(Bitmap));
Bitmap b = (Bitmap)tc.ConvertFrom(byteArray);
return b;
}
return null;
}
None of the above methods worked. Kindly help.
Image.FromStream() expects a stream that contains ONLY one image!
It resets the stream.Position to 0. I've you have a stream that contains multiple images or other stuff, you have to read your image data into a byte array and to initialize a MemoryStream with that:
Image.FromStream(new MemoryStream(myImageByteArray));
The MemoryStream has to remain open as long as the image is in use.
I've learned that the hard way, too.
Maybe the image is embedded in an OLE field and you have to consider the 88 bytes OLE header plus payload:
byteBlobData = (Byte[]) reader.GetValue(0);
stream = new MemoryStream(byteBlobData, 88, byteBlobData.Length - 88);
img = Image.FromStream(stream);
I'm guessing that something is going wrong when receiving the file from the server. Perhaps you're only getting part of the file before trying to convert it to an Image? Are you sure it's the exact same byte array you're feeding the C++ application?
Try saving the stream to a file and see what you get. You might be able to uncover some clues there.
You can also add a breakpoint and manually compare some of the bytes in the byte array to what they're supposed to be (if you know that).
Edit: It looks like there's nothing wrong with receiving the data. The problem is that it's in raw format (not a format that Image.FromStream understands). The Bitmap(Int32, Int32, Int32, PixelFormat, IntPtr) constructor may be of use here. Or, you can create the blank bitmap and blt it manually from the raw data.
I've had this problem when doing this:
MemoryStream stream = new MemoryStream();
screenshot.Save(stream, ImageFormat.Png);
byte[] bytes = new byte[stream.Length];
stream.Save(bytes, 0, steam.Length);
With the last 2 lines being the problem. I fixed it by doing this:
MemoryStream stream = new MemoryStream();
screenshot.Save(stream, ImageFormat.Png);
byte[] bytes = stream.ToArray();
And then this worked:
MemoryStream stream = new MemoryStream(bytes);
var newImage = System.Drawing.Image.FromStream(stream);
stream.Dispose();
System.InvalidArgument means The stream does not have a valid image format, i.e. an image type that is not supported.
Try this:
public Image byteArrayToImage(byte[] item)
{
Image img=Image.FromStream(new MemoryStream(item));
img.Save(Response.OutputStream, ImageFormat.Gif);
return img;
}
Hope it helps!
I've had the same problem in the past and it was caused by a leak within the windows GDI libraries, which is what 'Bitmap' uses. If this happening all the time for you then its probably unrelated, however.
this code is working
string query="SELECT * from gym_member where Registration_No ='" + textBox9.Text + "'";
command = new SqlCommand(query,con);
ad = new SqlDataAdapter(command);
DataTable dt = new DataTable();
ad.Fill(dt);
textBox1.Text = dt.Rows[0][1].ToString();
textBox2.Text = dt.Rows[0][2].ToString();
byte[] img = (byte[])dt.Rows[0][18];
MemoryStream ms = new MemoryStream(img);
pictureBox1.Image = Image.FromStream(ms);
ms.Dispose();
Try to use something similar to what is described here https://social.msdn.microsoft.com/Forums/vstudio/en-US/de9ee1c9-16d3-4422-a99f-e863041e4c1d/reading-raw-rgba-data-into-a-bitmap
Image ImageFromRawBgraArray(
byte[] arr,
int charWidth, int charHeight,
int widthInChars,
PixelFormat pixelFormat)
{
var output = new Bitmap(width, height, pixelFormat);
var rect = new Rectangle(0, 0, width, height);
var bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat);
// Row-by-row copy
var arrRowLength = width * Image.GetPixelFormatSize(output.PixelFormat) / 8;
var ptr = bmpData.Scan0;
for (var i = 0; i < height; i++)
{
Marshal.Copy(arr, i * arrRowLength, ptr, arrRowLength);
ptr += bmpData.Stride;
}
output.UnlockBits(bmpData);
return output;
}
After load from DataBase byteArray has more byte than one image. In my case it was 82.
MemoryStream ms = new MemoryStream();
ms.Write(byteArray, 82, byteArray.Length - 82);
Image image = Image.FromStream(ms);
And for save in the DB I insert 82 byte to begin stream. Properties.Resources.ImgForDB - it is binary file that contain those 82 byte. (I get it next path - Load Image from DB to MemoryStream and save to binary file first 82 byte. You can take it here - https://yadi.sk/d/bFVQk_tdEXUd-A)
MemoryStream temp = new MemoryStream();
MemoryStream ms = new MemoryStream();
OleDbCommand cmd;
if (path != "")
{
Image.FromFile(path).Save(temp, System.Drawing.Imaging.ImageFormat.Bmp);
ms.Write(Properties.Resources.ImgForDB, 0, Properties.Resources.ImgForDB.Length);
ms.Write(temp.ToArray(), 0, temp.ToArray().Length);
cmd = new OleDbCommand("insert into Someone (first, Second, Third) values (#a,#b,#c)", connP);
cmd.Parameters.AddWithValue("#a", fio);
cmd.Parameters.AddWithValue("#b", post);
cmd.Parameters.AddWithValue("#c", ms.ToArray());
cmd.ExecuteNonQuery();

Categories

Resources