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
This may be an existing question but the answers I got is not exactly what I'm looking for.
In C# Winforms, I want to convert the image (not the path) from the picturebox and convert it into Byte array and display that Byte array in label.
Currently, this is what I have.
Byte[] result = (Byte[]) new ImageConverter().ConvertTo(pbOrigImage.Image, typeof(Byte[]));
Then, after displaying the Byte array in label, I want to convert it from Byte array to image. I currently don't have codes when it comes to image to Byte array conversion. But is this possible?
You can use the following methods for conversion from byte[] to Image,
public byte[] ConvertImageToBytes(Image img)
{
byte[] arr;
using (MemoryStream ms = new MemoryStream())
{
Bitmap bmp = new Bitmap(img);
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
arr = ms.ToArray();
}
return arr;
}
public Image ConvertBytesToImage(byte[] arr)
{
using (MemoryStream ms = new MemoryStream(arr))
{
return Bitmap.FromStream(ms);
}
}
To convertbyte[] to a string or vice-versa, you can refer to this
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:\
I am asking the user to upload an image, which can be in any image format.
I pass the base64 data to my .Net controller, as well as the filename (From which, I can get the extension).
I am then converting that base64 string into an Image.
public static Image Base64ToImage(string base64String)
{
// Convert base 64 string to byte[]
byte[] imageBytes = Convert.FromBase64String(base64String);
// Convert byte[] to Image
using (var ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
Image image = Image.FromStream(ms, true);
return image;
}
}
I get an error:
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters
I think it's because the base64 string has:
"data:image/jpeg;base64,/9j/4AAQSkZJRgABA ...." at the start.
So I need to trim off the "data:image/jpeg;base64,", and then save it? As I am removing data about the file type, do I need to specify it somewhere else?
All the examples I find don't seem to trim anything off the front. They just save the string. I'm guessing, something on my side is adding that header?
Hi Please find a version of working converters i had been using in the past,
Do tell if you need more explanation.
Seems like your conversion to base64 is the culprit!
/// <summary>
///1 Convert String to Image
/// </summary>
/// <param name="commands"></param>
/// <returns></returns>
public Image ConvertStringtoImage(string commands)
{
byte[] photoarray = Convert.FromBase64String(commands);
MemoryStream ms = new MemoryStream(photoarray, 0, photoarray.Length);
ms.Write(photoarray, 0, photoarray.Length);
Image image = System.Drawing.Image.FromStream(ms);
return image;
}
/// <summary>
///2. Read picture from Database and return as image
/// just change the mysql to sql server type.
/// </summary>
/// <param name="commands"></param>
/// <returns></returns>
public Image Readphotofromdb(string commands)
{
Image image = null;
using (MySqlConnection dbConn = new MySqlConnection(connector))
{
using (MySqlCommand cmd = new MySqlCommand(commands, dbConn))
{
dbConn.Open();
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
byte[] photoarray = Convert.FromBase64String(reader.GetString(0));
MemoryStream ms = new MemoryStream(photoarray, 0, photoarray.Length);
ms.Write(photoarray, 0, photoarray.Length);
image = new Bitmap(ms);
}
}
}
}
MySqlConnection.ClearAllPools();
return image;
}
/// <summary>
/// 3. Convert Image to base64 string
/// </summary>
/// <param name="image"></param>
/// <returns></returns>
public string ConvertImageToString(Image image)
{
byte[] byteArray = new byte[0];
using (MemoryStream stream = new MemoryStream())
{
image.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Close();
byteArray = stream.ToArray();
}
string base64String = Convert.ToBase64String(byteArray);
return base64String;
}
use image data like
/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQ......9= instead of
data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQ..
....9=
private void GetImage(){
string imagedata="/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQ..
....9=";
Image image=ImageFromBase64(imagedata);
}
public static Image ImageFromBase64(string base64String)
{
byte[] imageBytes = Convert.FromBase64String(base64String);
using (var ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
Image image = Image.FromStream(ms, true);
return image;
}
}
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);
Hi I can’t find sample for convert MULTI PAGE tiff image to byte array.
For convert byte array to Tiff I use this method
public static Tiff CreateTiffFromBytes(byte[] bytes)
{
using (var ms = new MemoryStream(bytes))
{
Tiff tiff = Tiff.ClientOpen("in-memory", "r", ms, new TiffStream());
return tiff;
}
}
EDITED:
This method convert TIFF image with more pages to byte Array. I think in this method will be root of problem.
//imageIn is tif image with 12 pages
public static byte[] ImageToByteArray(System.Drawing.Image imageIn)
{
using (var ms = new MemoryStream())
{
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Tiff);
return ms.ToArray();
}
}
public static List<System.Drawing.Image> GetAllPages(System.Drawing.Image multiTiff)
{
var images = new List<System.Drawing.Image>();
var bitmap = (Bitmap)multiTiff;
int count = bitmap.GetFrameCount(FrameDimension.Page);
for (int idx = 0; idx < count; idx++)
{
bitmap.SelectActiveFrame(FrameDimension.Page, idx);
using (var byteStream = new MemoryStream())
{
bitmap.Save(byteStream, ImageFormat.Tiff);
images.Add(System.Drawing.Image.FromStream(byteStream));
}
}
return images;
}
After conversion to byte array I lose pages.
Image from byte array has only one page.
Image src = Image.FromFile(source);
//imagesInSource.Count (pages) is 12
List<Image> imagesInSource = GetAllPages(src);
byte[] imageData = ImageToByteArray(src);
Image des = ImageConvert.ByteArrayToImage(imageData);
//imagesInSource.Count (pages) is 1
List<Image> imagesInDes = GetAllPages(des);
I am not sure why you can't send TIFF file to the service? The file is just bytes, after all.
And your code in the first snippet is incorrect because you dispose memory stream that is passed to Tiff object. You shouldn't do that. The Tiff object will dispose the stream itself.
EDIT:
In the third snippet you create images for each page of the System.Drawing.Image but the you convert only first produced image to byte array. You should use something like
List<byte[]> imagesBytes = new List<byte[]>();
foreach (Image img in imagesInSource)
{
byte[] imageData = ImageToByteArray(src);
imageBytes.Add(imageData);
}
Then you should send imagesBytes to your server and create several TIFF images from that.
Anyway, it seems like you should think more about what are you really trying to do. Because for now it unclear to me what all these conversions are for.