I'm using this function to convert base64 to image.
public Image Base64ToImage(string base64String)
{
// Convert Base64 String to byte[]
byte[] imageBytes = Convert.FromBase64String(base64String);
using (var ms = new MemoryStream(imageBytes, 0,imageBytes.Length))
{
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
//Image image = Image.FromStream(ms, true);
Image image = Image.FromStream(ms,true,true);
return image;
}
}
but it is not working. please help me.
I don't thik the ms write call is needed here.
using (var ms = new MemoryStream(imageBytes, 0,imageBytes.Length))
{
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
Your are efectively constructing the stream from your byteArray so the ms.Write call will append the data twice in the stream. This might cause issues for your Image object. Either use the default constructor for the stream or delete the Write and test again.
Edit:
Zey deleted his answer but i think he had a good point in there. You might consider dropping the using block as well. My memory might fail me but i think Image objects need the source stream to be kept open. Dispose the Image object when not needed anymore.
Related
I need to convert a JBIG1 image to another image format, such as JPEG or PNG, but I can't seem to find anything related to this.
This JBIG1 image is received encoded in Base64.
I've tried using System.Drawing in .NET to accomplish this, but a "System.ArgumentException: Parameter is not valid" exception is thrown on calling Image.FromStream() using the JBIG1 byte array data.
See code below:
byte[] binData = ConvertFromBase64StringToArray("BASE64 ENCODED JBIG1 IMAGE GOES HERE");
Image img = binData.ConvertToImage();
img.Save("C:/Images/converted-from-jbig.jpeg", System.Drawing.Imaging.ImageFormat.Jpeg);
Functions used:
public static byte[] ConvertFromBase64StringToArray(string base64String)
{
byte[] data = Convert.FromBase64String(base64String);
using (var stream = new MemoryStream(data, 0, data.Length))
{
data = stream.ToArray();
}
return data;
}
public static Image ConvertToImage(this byte[] byteArrayIn)
{
var ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms); //exception thrown in this line
return returnImage;
}
Does anyone have any knowledge to share about this topic?
You'll probably need a third party library to work with JBig files. It looks like https://github.com/dlemstra/Magick.NET has support for that.
I am trying to do some inferences on a SageMaker endpoint in C# using a InvokeEndpointRequest object. My inference body is a PNG or JPEG image. However, SageMaker requires an application/x-recordio-protobuf format. How can I convert my image file into this format to be able to use InvokeEndpoint with the above object.
InvokeEndpointRequest invokeRequest = new InvokeEndpointRequest
{
EndpointName = "kmeans-2019-xx-xx-xx-xx-xx-xxx",
Body= GetImageFromFile(),
ContentType= "application/x-recordio-protobuf"
};
InvokeEndpointResponse invokeResponse = smClient.InvokeEndpoint(invokeRequest);
For the moment the GetImageFromFile method just reads an image file and transforms it in MemoryStream:
Stream stream = openFileDialog.OpenFile();
byte[] data = new byte[stream.Length];
stream.Read(data, 0, (int)stream.Length);
MemoryStream ms=new MemoryStream(data);
return ms;
I tried to serialize the MemoryStream by using Protobuf-net, but it does not work.
You can first convert your PNG image into a numpy array (this can be done using PIL, OpenCV, or through other libraries).
Once you have the image represented as a ndarray, convert it to protobuf recordIO format as shown in this example.
I have an image converted to a base64 string that I need to convert back to an image and attach to a MailMessage.
Here is the relevant code converting it from base64 string to image (I think I can skip the Image object and do this using one memory stream, but had some issues implementing that). Attempting to save the Image to a MemoryStream throws a generic GDI+ error:
Image image = ImageHelper.Base64ToImage(attachment.FieldData);
if (image != null)
{
using (var ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png); // Throws a generic GDI+ error on Save
ms.Position = 0;
var imageAttachment = new Attachment(ms, "image.png", "image/png");
message.Attachments.Add(imageAttachment);
}
}
public static class ImageHelper
{
public static Image Base64ToImage(string base64String)
{
if (string.IsNullOrEmpty(base64String))
{
return null;
}
byte[] imageBytes = Convert.FromBase64String(base64String);
using (var ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
ms.Write(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(ms, true);
return image;
}
}
}
I'm able to serve up the raw base64 string elsewhere using an img tag and it works fine so I'm confident that the problem isn't with the base64 string itself:
<img src="data:image/png;base64,<myBase64StringHere>" alt="My Image" width="500" />
I must be doing something wrong in converting it back, but I haven't been able to figure out the issue. Thanks for any help with this!
Image.FromStream(Stream) says, "You must keep the stream open for the lifetime of the Image", but your using statement disposes the stream as the Image is returned. A workaround would be to return both the image and the stream together as a tuple and without the using:
public static Tuple<Image, MemoryStream> Base64ToImage(string base64String)
{
if (string.IsNullOrEmpty(base64String))
{
return null;
}
byte[] imageBytes = Convert.FromBase64String(base64String);
var ms = new MemoryStream(imageBytes, 0, imageBytes.Length)
ms.Write(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(ms, true);
return new Tuple<Image, MemoryStream>(image, ms);
}
Also note to take care and view each overload on the MSDN pages. Normally I would say, "view the most encompassing overload to get all the remarks and notes", but in this case that is not true. The MSDN page for the biggest overload, Image.FromStream Method (Stream, Boolean, Boolean) does not mention that you need to keep the stream open, but I am fairly certain that is a mistake on that particular page.
I'm having some difficulty saving a stream of bytes from an image (in this case, a jpg) to a System.IO.MemoryStream object. The goal is to save the System.Drawing.Image to a MemoryStream, and then use the MemoryStream to write the image to an array of bytes (I ultimately need to insert it into a database). However, inspecting the variable data after the MemoryStream is closed shows that all of the bytes are zero... I'm pretty stumped and not sure where I'm doing wrong...
using (Image image = Image.FromFile(filename))
{
byte[] data;
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
data = new byte[m.Length];
m.Write(data, 0, data.Length);
}
// Inspecting data here shows the array to be filled with zeros...
}
Any insights will be much appreciated!
To load data from a stream into an array, you read, not write (and you would need to rewind). But, more simply in this case, ToArray():
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
data = m.ToArray();
}
If the purpose is to save the image bytes to a database, you could simply do:
byte[] imgData = System.IO.File.ReadAllBytes(#"path/to/image.extension");
And then plug in your database logic to save the bytes.
I found for another reason this article some seconds ago, maybe you will find it useful:
http://www.codeproject.com/KB/recipes/ImageConverter.aspx
Basically I don't understand why you try to write an empty array over a memory stream that has an image. Is that your way to clean the image?
If that's not the case, read what you have written in your memorystream with ToArray method and assign it to your byte array
And that's all
Try this way, it works for me
MemoryStream ms = new MemoryStream();
Bitmap bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(bmp, panel1.Bounds);
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] Pic_arr = new byte[ms.Length];
ms.Position = 0;
ms.Read(Pic_arr, 0, Pic_arr.Length);
ms.Close();
Well instead of a Image control, I used a Panel Control.
How can I convert a BITMAP in byte array format to JPEG format using .net 2.0?
What type of byte[] do you mean? The raw file-stream data? In which case, how about something like (using System.Drawing.dll in a client application):
using(Image img = Image.FromFile("foo.bmp"))
{
img.Save("foo.jpg", ImageFormat.Jpeg);
}
Or use FromStream with a new MemoryStream(arr) if you really do have a byte[]:
byte[] raw = ...todo // File.ReadAllBytes("foo.bmp");
using(Image img = Image.FromStream(new MemoryStream(raw)))
{
img.Save("foo.jpg", ImageFormat.Jpeg);
}
If it is just a buffer of raw pixel data, and not a complete image file(including headers etc., such as a JPEG) then you can't use Image.FromStream.
I think what you might be looking for is System.Drawing.Bitmap.LockBits, returning a System.Drawing.Imaging.ImageData; this provides access to reading and writing the image's pixels using a pointer to memory.
public static Bitmap BytesToBitmap(byte[] byteArray)
{
using (MemoryStream ms = new MemoryStream(byteArray))
{
Bitmap img = (Bitmap)Image.FromStream(ms);
return img;
}
}