I have some C# code that converts an image to base64 string. The code is :
MemoryStream ms = new MemoryStream();
Image img = Image.FromFile(filename);
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
string s = Convert.ToBase64String(ms.GetBuffer());
I am trying to implement it with JAVA. my java code is :
BufferedImage img = null;
img = ImageIO.read(new File(filename));
byte[] bytes = ((DataBufferByte)img.getData().getDataBuffer()).getData();
String js = Base64.encodeBase64String(bytes);
this two piece of code should return the same string for the same image file. But they are returning different strings. I am unable to figure out why. Can anyone shed some light on it?
this two piece of code should return the same string for the same image file
No, they really shouldn't.
The C# code is returning the base64 representation of a JPEG-encoded version of the image data - and potentially some 0s at the end, as you're using GetBuffer instead of ToArray. (You want ToArray here.)
The Java code is returning the base64 representation of the raw raster data, according to its SampleModel. I'd expect this to be significantly larger than the string returned by the C# code.
Even if both pieces of code encoded the image with the same format, that doesn't mean they'll come up with the exact same data - it will depend on the encoding.
Importantly, if you just want "the contents of the file in base64" then you don't need to go via an Image at all. For example, in C# you could use:
string base64 = Convert.ToBase64String(File.ReadAllBytes(filename));
The fact that it's an image is irrelevant in that respect - the file is just a collection of bytes, and you can base64-encode that without understanding the meaning of those bytes at all.
Related
I'm receiving a base64 string from the client side that represents a jpg and I'm saving it using the following code
byte[] imageBytes = Convert.FromBase64String(base64File.base64Data);
using (var ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
Image image = Image.FromStream(ms, true);
image.Save("aPath");
}
The problem is that that the original image entered on the client side (before the base64 encoding) is about 3MB and once that I save it using the method above, it turns to be a 24MB image!
Is there any way to reduce it's size? (I know that sending big images encoded in base64 is not very smart, but I need to find a solution keeping this part)
Just save the bytes, don't convert it back into an image, otherwise you will have to use the same settings as when it was originally saved.
I.e its already the image you want, loading it from a stream and calling save, saves it as a bitmap in probably 32bit
Update
So I tried the code below
byte[] imageBytes = Convert.FromBase64String(base64File.base64Data); File.WriteAllBytes("apath"),imageBytes);
But it generates a 18MB file,
still much larger than the original
Basically this means, when ever you are converting it base64 (server side), it is probably doing the same thing. Maybe its loading it into an Image and saving the bytes before converting it to Base64.
I believe a way to tell if the image is actually a bitmap (in your case) before conversion base64, is just look to see if the first 2 bytes of the file are BM.
Either way, the image is being manipulated on the other side before its converted to base64, maybe its a bitmap or its just reenconding it, its hard to tell. That's to say base64 encoding isn't smart enough to reenconde the image format and inflate the size
I'm trying to convert several byte arrays (stored in SQL Server 2008 R2 as varbinary(8000)) into images so I can attach them to a PDF file (an example of the data is below). I keep getting "Parameter is not valid." when creating the Image from the MemoryStream. Any help on this?
MemoryStream memoryStream = new MemoryStream(byteArray);
Image image = Image.FromStream(memoryStream);
Bitmap bitmap = new Bitmap(image);
0x0A020101000000005E006500FA00FA0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010C00010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C1C0C7000FC2FFC1FE80C70007C2FFC1FE1FC7FFC1F03FC1FFC1FE3FC7FFC1F807C1FFC1FE3FC8FFC1F3C1FFC1FE3FC8FFC1FEC1FFC1FE3FC8FFC1FE7FC1FE3FC9FFBFC1FE3FC9FFC1DFC1FE3FC9FFC1CFC1FE3FC9FFC1F3C1FE3FC9FFC1FBC1FE3FC9FFC1F9C1FE3FC9FFC1F9C1FE3FC9FFC1FCC1FE3FC9FFC1FE7E3FC9FFC1FE7E3FCAFF7E3FC2FFC1FCC20007C4FF3E3FC2FFC1F8C300C4FF3E3FC2FFC1F1C2FFC1FC7FC3FF3E3FC2FFC1F1C2FFC1FC3FC3FF3E3FC2FFC1F1C3FF9FC3FF3E3FC2FFC1F1C3FFC1CFC3FF3E3FC2FFC1F1C3FFC1E7C3FF3E3FC2FFC1F1C3FFC1F3C3FF3E3FC2FFC1F1C3FFC1F3C3FF3E3FC2FFC1F1C3FFC1F3C3FF3E3FC2FFC1F1C3FFC1F3C3FF3E3FC2FFC1F1C3FFC1F3C3FF3E3FC2FFC1F1C3FFC1F3C3FF3E3FC2FFC1F1C3FFC1F3C2FFC1FE7E3FC2FFC1F1C3FFC1E7C2FFC1FE7E3FC2FFC1F1C3FFC1C7C2FFC1FCC1FE3FC2FFC1F1C3FFC1C7C2FFC1F9C1FE3FC2FFC1F1C3FFC1DFC2FFC1F9C1FE3FC2FFC1F1C3FFBFC2FFC1F9C1FE3FC2FFC1F1C2FFC1FC3FC2FFC1F3C1FE3FC2FFC1F0C2FFC1F8C3FFC1E7C1FE3FC2FFC1FEC2000FC3FFC1CFC1FE3FC3FFC2000FC3FF9FC1FE3FC9FF3FC1FE3FC8FFC1FE7FC1FE3FC8FFC1F0C1FFC1FE3FC8FFC1E7C1FFC1FE3FC8FFC1CFC1FFC1FE3FC8FF8FC1FFC1FE3FC8FFC1E0C1FFC1FE3FC8FFC1F8C1FFC1FE3FC8FFC1FC1FC1FE3FC9FF8FC1FE3FC9FFC1E7C1FE3FC9FFC1F0C1FE3FC9FFC1FE7E3FCAFF7E3FC2FFC1FCC300C4FF3E3FC2FFC1F8C3001FC3FF3E3FC2FFC1F1C3FF8FC3FF9E3FC2FFC1F1C3FF87C3FFC1CE3FC2FFC1F1C3FFC1F3C3FFC1CE3FC2FFC1F1C3FFC1F9C3FFC1EE3FC2FFC1F1C3FFC1FCC3FFC1E43FC2FFC1F1C3FFC1FE7FC2FFC1E43FC2FFC1F1C4FF3FC2FFC1E43FC2FFC1F1C4FF1FC2FFC1F03FC2FFC1F1C4FF1FC2FFC1F83FC2FFC1F1C4FF1FC2FFC1F83FC2FFC1F1C4FF1FC2FFC1F83FC2FFC1F1C4FF1FC2FFC1F83FC2FFC1F1C4FF1FC2FFC1F83FC2FFC1F1C4FF1FC2FFC1F83FC2FFC1F1C4FF1FC2FFC1F83FC2FFC1F1C3FFC1FE7FC2FFC1F83FC2FFC1F1C3FFC1FEC3FFC1F83FC2FFC1F1C3FFC1F9C3FFC1F83FC2FFC1F1C3FFC1F3C3FFC1F83FC2FFC1F1C3FFC1F7C3FFC1F83FC2FFC1F1C2FFC1FE0FC3FFC1F83FC2FFC1F0C3003FC3FFC1F83FC2FFC1F8C20001C4FFC1F83FC2FFC1FCC20003C4FFC1FC3FCAFFC1E43FCAFFC1E43FCAFFC1E43FCAFFC1EE3FCAFFC1EE3FCAFFC1CE3FCAFF3E3FCAFF7E3FC9FFC1FE7E3FC9FFC1FE7E3FC9FFC1FCC1FE3FC9FFC1F1C1FE3FC9FFC1C3C1FE3FC9FFC1DFC1FE3FC9FF9FC1FE3FC8FFC1E07FC1FE3FC8FFC1C1C1FFC1FE1FC7FF001FC1FFC1FEC9003FC1FFC1FE80C700C3FFC1FEC1C0C700C3FFC1FE
It's a
% file output
output: PCX ver. 2.8 image data, with palette
under linux I just transformed your hex stream from plain text to a binary file called output
echo
"0A020101000000005E006500FA00FA0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010C00010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C1C0C7000FC2FFC1FE80C70007C2FFC1FE1FC7FFC1F03FC1FFC1FE3FC7FFC1F807C1FFC1FE3FC8FFC1F3C1FFC1FE3FC8FFC1FEC1FFC1FE3FC8FFC1FE7FC1FE3FC9FFBFC1FE3FC9FFC1DFC1FE3FC9FFC1CFC1FE3FC9FFC1F3C1FE3FC9FFC1FBC1FE3FC9FFC1F9C1FE3FC9FFC1F9C1FE3FC9FFC1FCC1FE3FC9FFC1FE7E3FC9FFC1FE7E3FCAFF7E3FC2FFC1FCC20007C4FF3E3FC2FFC1F8C300C4FF3E3FC2FFC1F1C2FFC1FC7FC3FF3E3FC2FFC1F1C2FFC1FC3FC3FF3E3FC2FFC1F1C3FF9FC3FF3E3FC2FFC1F1C3FFC1CFC3FF3E3FC2FFC1F1C3FFC1E7C3FF3E3FC2FFC1F1C3FFC1F3C3FF3E3FC2FFC1F1C3FFC1F3C3FF3E3FC2FFC1F1C3FFC1F3C3FF3E3FC2FFC1F1C3FFC1F3C3FF3E3FC2FFC1F1C3FFC1F3C3FF3E3FC2FFC1F1C3FFC1F3C3FF3E3FC2FFC1F1C3FFC1F3C2FFC1FE7E3FC2FFC1F1C3FFC1E7C2FFC1FE7E3FC2FFC1F1C3FFC1C7C2FFC1FCC1FE3FC2FFC1F1C3FFC1C7C2FFC1F9C1FE3FC2FFC1F1C3FFC1DFC2FFC1F9C1FE3FC2FFC1F1C3FFBFC2FFC1F9C1FE3FC2FFC1F1C2FFC1FC3FC2FFC1F3C1FE3FC2FFC1F0C2FFC1F8C3FFC1E7C1FE3FC2FFC1FEC2000FC3FFC1CFC1FE3FC3FFC2000FC3FF9FC1FE3FC9FF3FC1FE3FC8FFC1FE7FC1FE3FC8FFC1F0C1FFC1FE3FC8FFC1E7C1FFC1FE3FC8FFC1CFC1FFC1FE3FC8FF8FC1FFC1FE3FC8FFC1E0C1FFC1FE3FC8FFC1F8C1FFC1FE3FC8FFC1FC1FC1FE3FC9FF8FC1FE3FC9FFC1E7C1FE3FC9FFC1F0C1FE3FC9FFC1FE7E3FCAFF7E3FC2FFC1FCC300C4FF3E3FC2FFC1F8C3001FC3FF3E3FC2FFC1F1C3FF8FC3FF9E3FC2FFC1F1C3FF87C3FFC1CE3FC2FFC1F1C3FFC1F3C3FFC1CE3FC2FFC1F1C3FFC1F9C3FFC1EE3FC2FFC1F1C3FFC1FCC3FFC1E43FC2FFC1F1C3FFC1FE7FC2FFC1E43FC2FFC1F1C4FF3FC2FFC1E43FC2FFC1F1C4FF1FC2FFC1F03FC2FFC1F1C4FF1FC2FFC1F83FC2FFC1F1C4FF1FC2FFC1F83FC2FFC1F1C4FF1FC2FFC1F83FC2FFC1F1C4FF1FC2FFC1F83FC2FFC1F1C4FF1FC2FFC1F83FC2FFC1F1C4FF1FC2FFC1F83FC2FFC1F1C4FF1FC2FFC1F83FC2FFC1F1C3FFC1FE7FC2FFC1F83FC2FFC1F1C3FFC1FEC3FFC1F83FC2FFC1F1C3FFC1F9C3FFC1F83FC2FFC1F1C3FFC1F3C3FFC1F83FC2FFC1F1C3FFC1F7C3FFC1F83FC2FFC1F1C2FFC1FE0FC3FFC1F83FC2FFC1F0C3003FC3FFC1F83FC2FFC1F8C20001C4FFC1F83FC2FFC1FCC20003C4FFC1FC3FCAFFC1E43FCAFFC1E43FCAFFC1E43FCAFFC1EE3FCAFFC1EE3FCAFFC1CE3FCAFF3E3FCAFF7E3FC9FFC1FE7E3FC9FFC1FE7E3FC9FFC1FCC1FE3FC9FFC1F1C1FE3FC9FFC1C3C1FE3FC9FFC1DFC1FE3FC9FF9FC1FE3FC8FFC1E07FC1FE3FC8FFC1C1C1FFC1FE1FC7FF001FC1FFC1FEC9003FC1FFC1FE80C700C3FFC1FEC1C0C700C3FFC1FE"
| xxd -p -r >output
and then the easy part with file output to get the name of the file format from the utility file.
First, make sure you know the encoding, as the Image.FromStream method knows only a limited number of formats.
Make sure that the Position of your MemoryStream is set properly to 0, and not to the end - otherwise, any reads will begin at the end appear to be empty, instead of starting at the beginning.
Also, note that
This constructor does not expose the underlying stream. GetBuffer throws UnauthorizedAccessException.1
Thus, this could be caused by some of the way Bitmap is handling the underlying stream. IF need be, try making an empty memorystream, copying the byte into it, and then resetting the position
MemoryStream memoryStream = new MemoryStream();
foreach(var b in byteArray) memoryStream.WriteByte(b);
memoryStream.Position = 0;
Image image = Image.FromStream(memoryStream);
The byte array you gave is 1117 bytes long. That's not evenly divisible by 4 or 3, so I'm pretty certain that the image is not raw bytes and is actually encoded in an image format of some sort.
The Image.FromStream() method can't decode an encoded image without knowing the format, and the byte array you gave doesn't specify what that format is. Therefore the parameter you gave is invalid. If you know the format of the image you could attempt to insert a header into the byte array before the rest of the image, and see if that helps. It's curious you have the image but not its header, although it doesn't appear to be a base-64 string either.
Without knowing the image format it could be difficult to convert these byte arrays into images. Is there any way you could find out what they are? How is the image data retrieved to be stored?
I need to convert an picture (that is stored in an object of type Image) to a string for storage (and later for conversion back into an Image object for display) in a metro app
I have found lots of answers for converting an image to a base64 string in .NET 4.0 etc but in 4.5 the System.Windows.Bitmap namespace isn't there (the Image class is in Windows.UI.Xaml.Media.Imaging) and the method that was in that namespace that made it possible in 4.0 "Save()" doesn't seem to be in 4.5...unless I just can't find it.
Theres an example of doing this here but like I said it doesn't work in a metro app/.NET 4.5
any ideas?
more details:
the method that will do this will convert an instance field that contains an image object (ive used its source property, is this correct?) and needs to store the resultant string from the conversion in an instance string field. this whole object can then be serialized, ignoring the Image field, with the hope of deserializing later and restoring the string to the Image field for display. so far ive tried to use a DataContractSerializer to serialize string from the image, but it doesn't seem to like it. Once I get a string from the image I would be able to serialize that, but its not something I've ever done before.
Also, it seems that the only .net 4.5 documentation that is definitely correct is the pages here: http://msdn.microsoft.com/library/windows/apps/
pages at the "normal looking" msdn site for .net 4.5 don't seem to always work in metro apps? (just a theory?)
[solved]
I finally got it! for anyone else that ever has to do this the answer is here: http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/38c6cb85-7454-424f-ae94-32782c036567/
I did this
var reader = new DataReader(myMemoryStream.GetInputStreamAt(0));
var bytes = new byte[myMemoryStream.Size];
await reader.LoadAsync((uint)myMemoryStream.Size);
reader.ReadBytes(bytes);
after this sequence, the byte array bytes will have the data from the stream in it, from there I set a string to the value of
Convert.ToBase64String(bytes);
I finally got it! for anyone else that ever has to do this the answer is here: http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/38c6cb85-7454-424f-ae94-32782c036567/
I did this
var reader = new DataReader(myMemoryStream.GetInputStreamAt(0));
var bytes = new byte[myMemoryStream.Size];
await reader.LoadAsync((uint)myMemoryStream.Size);
reader.ReadBytes(bytes);
after this sequence, the byte array bytes will have the data from the stream in it, from there I set a string to the value of
Convert.ToBase64String(bytes);
I'm not sure of this because I do not have the .net 4.5 installed here, but I think this could work:
You could use the BitmapSource.CopyPixels() method to extract the pixels of the image:
http://msdn.microsoft.com/en-us/library/ms616043(v=vs.110).aspx
Then use Convert.ToBase64String() to do the convertion.
Also, here are some useful imaging HOW-TOs:
http://msdn.microsoft.com/en-us/library/ms750864(v=vs.110)
Try BitmapEncoder. Example of how to create a BitmapEncoder here. The appropriate namespace is Windows.Graphics.Imaging.
BitmapEncoder gets you an encoder. You can then use GetPixelDataAsync(BitmapPixelFormat, BitmapAlphaMode, BitmapTransform, ExifOrientationMode, ColorManagementMode) to get your pixel data. Following that you can use any generic C# base64 encoder.
(Examples are Javascript but should work for C# as well since the classes exist in C#)
You should store the encoded format of image (say JPEG) format, decoded back to byte[], create a MemoryStream, then Metro BitmapImage can be created from the stream.
I'm trying to produce a system which takes an image in OpenCV, writes it to XML, reads it from XML, and displays it in an Image control in a WPF application.
The problem I'm having is that I'm unclear as to how .NET classes (e.g. BitmapImage) process images from a byte array. I've tried a number of methods and gotten various errors - too numerous to post unless required.
I was wondering if someone could point me in the right direction regarding this? What I want to know is how does the data need to be presented to a .NET object in order to display it in an Image control?
Thanks in advance for your help - it is much appreciated.
EDIT: I expect what I need to do is convert the XML into a byte array and use that, along with a definition of the format, to instantiate a BitmapImage object or equivalent to use as source for the Image control. What I'm not sure of is how to do this.
Use int cvSaveImage(const char* filename, const CvArr* image)
to save the file as an Image.The image format is chosen based on the filename extension
No need to store it in XML if you can directly store it as Image file.
The .NET classes requires an Image.That's it.
Note:
If you want to store red,green,blue values as comma separated strings, it would be very inefficient.Save it in Base64 instead.You can then convert it into bytes and feed it to any .NET image class.Also the .NET ImageConverter Class may be very helpful.
I found that the issue was (presumably) that I wasn't Base64 encoding the XML data before writing it. Thus the solution is to Base64 encode the data before writing to XML, Base64 decoding it on the other side, reading the data as a byte array and using that to instantiate a MemoryStream and then a BitmapImage object.
Thanks for your help everyone.
You can use:
public static BitmapSource Create(
int pixelWidth,
int pixelHeight,
double dpiX,
double dpiY,
PixelFormat pixelFormat,
BitmapPalette palette,
Array pixels,
int stride
)
I'm trying to save image into sql-server using linq. I set the field type to be image, in my application I use a fileupload controler to read the image file as byte[]. Here comes the question, it cannot convert byte[] to binary when I evaluate the image field. Do you think it's a good way to save image?
My code:
Stream imgStream = FileUpload1.PostedFile.InputStream;
int imglen = FileUpload1.PostedFile.ContentLength;
string imgContentType = FileUpload1.PostedFile.ContentType;
string imgName = FileUpload1.PostedFile.FileName;
byte[] imgBinaryData = new byte[imglen];
int n = imgStream.Read(imgBinaryData, 0, imglen);
ImgStore info = new ImgStore();
info.pic = imgBinaryData;// it cannot implictly convert type 'byte[]' to Linq.Binary
info.type = imgContentType;
info.fileName = imgName;
Storing images with LINQ to SQL: Converting byte array or stream to Binary
To convert a byte array to a LINQ Binary, you can utilize the Binary constructor:
MyObject.BinaryProperty = new Binary(bytes);
References
LINQ's Binary - MSDN
Binary Constructor - MSDN
Using LINQ to store images is going to be very inefficient because all APIs require at least one complete in-memory byte array the of image size. Even under moderate load this breaks quickly as the memory gets exhausted in spurious large array copies. I recommend you use streaming semantics, which avoid the problem of passing in and out large byte arrays into the ADO.Net API. See these two articles for complete working code which takes the HTTP POST uploaded file as a stream and transfers it into the database in a buffered stream (chuncked) manner, and similarly transfers the image from the database to the HTTP response in a similar fashion:
Download and Upload images from SQL Server via ASP.Net MVC
FILESTREAM MVC: Download and Upload images from SQL Server
The code is also available on CodeProject.