Rotate byte array Image and encode to Base64 string - c#

I am having a very difficult time trying to figure this one out:
I am working with a front-end which
Reads an image taken from a mobile device to a byte array
Converts the byte array to be stored as a Base64 string
Sends the Base64 string to a database
The back-end is only slated to store images as Base64 strings, as it later embeds the image as a Base64 string to an email for the user whose email application will only show Base64-embedded images. The problem is that the images are embedding 90 degrees counter-clockwise in the email, so I am trying to rotate the image 90 degrees before encoding the base64 string which is inserted into a Sql stored procedure (executed from the application). I feel like this code should simply do the trick:
HttpPostedFile img = imageUpload.PostedFile;
Stream stream = img.InputStream;
BinaryReader binaryReader = new BinaryReader(stream);
byte[] bytes = binaryReader.ReadBytes((int)stream.Length);
// Rotate Image Code (help):
using (var memoryStream = new MemoryStream(bytes))
{
var rotateImage = System.Drawing.Image.FromStream(memoryStream); rotateImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
rotateImage.Save(memoryStream, rotateImage.RawFormat);
bytes = memoryStream.ToArray();
}
// End Rotate Image Code
insert.Parameters.AddWithValue("#Image",Convert.ToBase64String(bytes));
But I am receiving an error when I try and run it:
System.ArgumentNullException: Value cannot be null.
Parameter name: encoder at the line "bytes = memoryStream.ToArray();"
When I try and save it as a jpeg the image gets chopped off at the top, but no other formats work.

I think there is a problem in the line:
rotateImage.Save(memoryStream, rotateImage.RawFormat);
Maybe you should specify the format. Try with:
rotateImage.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
Or even better, you can catch and force convertion only when there is an exception:
try
{
rotateImage.Save(memoryStream, rotateImage.RawFormat);
}
catch (System.ArgumentNullException)
{
rotateImage.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}
I think the issue is related to this answer

Related

C# Convert.ToBase64String always rotate my image 90 degrees counter clockwise

I'm working on a function that takes a photo and convert it to base64 string. But for some reason, and i tried looking this up, Convert.ToBase64String always rotate my image 90 degrees counter clockwise. I have tried looking this up but couldnt find anyone with similair issue. Here's the code
private async Task<string> GetPhotoBase64StringAsync(int compressionQuality = 50, PhotoSize photoSize = PhotoSize.Medium)
{
string filename = $"{DateTime.Now.ToString("MMddyyyy_Hmmtt")}.jpg";
var photo = await UtilityService.OpenCameraAsync(filename, compressionQuality, photoSize);
if (photo != null)
{
var bytes = await photo.GetStream().ConvertToBytes();
var base64string = Convert.ToBase64String(bytes);
return base64string
}
return string.Empty;
}
photo is an object that is returned by the xamarin plugin that im using. I know for a fact that the plugin returns the image in the right orientation because i displayed afterward and its not rotated.
The problem happens when i convert the image to stream and from stream to base64. If i put a breakpoint at return base64string and copy and paste the base64 string to an online base64 to image convert, the image would come out rotated 90 degrees counter clockwise.
I have also tried
var base64string = bytes.ToBase64String(); but that didnt work either.
This is so strange and i have never countered this before.
Have you tried the good old IO.MemoryStream instead of .ConvertToBytes()?
byte[] bytes;
using (var memoryStream = new System.IO.MemoryStream())
{
photo.GetStream().CopyTo(memoryStream);
bytes = memoryStream.ToArray();
}
the problem was with the plugin. I'm using MediaPlugin and had to use the other getstream method
var bytes = await photo.GetStreamWithImageRotatedForExternalStorage().ConvertToBytes();
var base64string = Convert.ToBase64String(bytes);
return base64string

base64 encoded image (.png) to byte[] insert into xml (open xml sdk) - ' ', hexadecimal value 0x0B, is an invalid character

This is a tricky one. I have a base64 encoded image passed from a client side app, to a c# API server side.
Upon receiving Server-side, I convert the image to a byte[], whereby I try to insert it into my Powerpoint Presentation Slide making use of the Open Xml Sdk.
From my searches on SO and the net, what I could find so far is that it is a problem with XML that don't allow certain characters, in this case 0x0B (a vertical tab if I'm not mistaken).
Now, I don't really know my options at this point, but the only other thing I can think of, is to save the image to disk first, then include it in my powerpoint programitacally but this is not ideal, as I want to do as little as possible directly on the disk, I don't even save the powerpoint on the disk, I email it directly from a Stream.
I can't "sanitize" the image for illegal chars, cause that would break the image, the same way as removing even just one of the characters in the raw base64 encoded string breaks it.
Is there any other alternative? Maybe someone who has had the same issue with normal XML and a byte[] of an image that somehow got a workaround? I include my code for my method below. (The code breaks on the last line, newSlidePart.Slide.Save(); with the following message:
' ', hexadecimal value 0x0B, is an invalid character. or "'\v', hexadecimal value 0x0B, is an invalid character."
Can anyone help please?
//assign imageID
const int imageIdStartId = 1;
string imgId = "ImgID" + imageIdStartId;
//Add new image part to slide
ImagePart imgPart = newSlidePart.AddImagePart(ImagePartType.Png, imgId);
//Feed the data to the new imgPart
imgPart.FeedData(new MemoryStream(imageAsBytes.ToArray()));
//find blip
Blip blip = newSlidePart.Slide.Descendants<Blip>().First();
//IMPORTANT - property embed refers to ppt image, point this to correct image ID, i.e. one just created.
blip.Embed = imgId;
//Finally save the slide
newSlidePart.Slide.Save();
Method for creating an image from my base64 string:
private byte[] CreateImageFromBase64String(string modelSceneImageContent)
{
try
{
string[] validImage = modelSceneImageContent.Split(',');
byte[] bytes = Convert.FromBase64String(validImage[1]);
#region if we want to save to an image
//Image image;
//using (MemoryStream ms = new MemoryStream(bytes))
//{
// image = Image.FromStream(ms);
// //FileStream fs = new FileStream(HttpContext.Current.ApplicationInstance.Server.MapPath(ConfigurationManager.AppSettings["TempImagePath"]), FileMode.Create);
// File.WriteAllBytes(HttpContext.Current.ApplicationInstance.Server.MapPath(ConfigurationManager.AppSettings["TempImagePath"]), bytes);
//}
#endregion
//return raw bytes for image replac in ppt (see above for image save to bmp then returning image as alternative)
return bytes;
}
catch (Exception ex)
{
Log.Exception(ex, "Error in powerpoint template retrieval.");
throw;
}
}

Converting a QImage to a C# Image

I have a QImage in my C++/Qt application and I would like to store it in a Microsoft SQL Database as a Bytearray. Afterwards, I would like to read it out with a Visual Studio C# Application as a ByteArray and convert it to an Image Object. To simplify :
QImage C++-->Bytearray-->Microsoft SQL-->Bytearray-->ImageC#
Is it possible with png-Pictures or is there an other solution for taking a picture with C++ storing in Microsoft SQL Server and read out with C#?
If I was doing this I would use use base64 as a string to store on the database.
Base64 is often used because it can represent binary data in an ASCII string and is perfect for storing on a database. The reason why base64 is used it that there is only 64 chars in the set and they are all printable characters (no funny weird symbols)
This is how I would go about it:
Step 1
First convert your QImage to a base64 string
QImage image;
image.load("test.png");
QByteArray byteArray;
QBuffer buffer(&byteArray);
image.save(&buffer, "PNG"); // writes the image in PNG format inside the buffer
QString base64Str = QString::fromLatin1(byteArray.toBase64().data())
Step 2
Save this string on the database
Step 3
In C# land, load the base64 string from the database and then convert it to an Image
public Image Base64ToImage(string base64String)
{
// Convert Base64 String to byte[]
byte[] imageBytes = Convert.FromBase64String(base64String);
MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
ms.Write(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(ms, true);
return image;
}
Note: The code above has not been tested!

Sending image with byte array convertion, from java to c#

I am trying to send a .jpg file which is on my android device to my server computer.
To do this, I am converting the picture into a byte array by a java android application, and sending it as an argument to my server computer. I`m doing this by a web service call.
The first function is edited:
public static byte[] ImageConvertion(){
File inputFile = new File("/storage/emulated/0/IFSpictures/icon-si_strapclamp.jpg");
byte[] data;
try{
FileInputStream input = new FileInputStream(inputFile);
ByteArrayOutputStream output = new ByteArrayOutputStream ();
byte[] buffer = new byte[65535];
int l;
while ((l = input.read(buffer)) > 0)
output.write (buffer, 0, l);
input.close();
output.close();
data = output.toByteArray();
return data;
} catch (IOException e) {
System.err.println(e);
data=null;
}
return data;
}
My web-service is written in ASP.NET (C#) language, and there is a function that takes the byte array as an argument and converts it back into an image on server computer.
[WebMethod]
public void ByteArrayToPicture(byte[] imageData)
{
using (var ms = new MemoryStream(imageData))
{
Image image = Image.FromStream(ms);
image.Save(#"C:\newImage.jpg");
}
}
However, I couldn`t do it because of the web-service side. I have debugged it that and it seems that the problem is because of the Image.FromStream() function.
I definitely don`t have any problems with passing the arguments. I think either, the language conflict or the conversion image to byte and vice-verse may be leading the problem. Does anyone has any idea or see something wrong?
I muchly appropriate any help.
Thanks.
sorry for my incomplete question, however I want to give some tips whoever is trying to do the same thing.
If anyone is trying to send an image to a server and both side has different platforms, then do not convert the image into byte array!
The reason is, in my case the image which is converted into byte array on Java differs from the byte array on C#. Therefore according to my research it is not possible to gather the image on the server side. The byte array created on Java wont have the right format on C#.
Hence anyone wants data transferring from one language to another, use Base64 encoding. Convert the image into Base64 string on one side and send it as string to the other language. Since Base64 format is same on every language there wont be any problem to reproduce it.
I sold the problem with the following codes:
Bitmap ourbitmap = BitmapFactory.decodeStream(imageStream, null, options);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ourbitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
test = Base64.encodeToString(b, Base64.DEFAULT);
This is the code where I get the image and convert it into Base64 string on Java android application,
byte[] imageBytes = Convert.FromBase64String(Base64ImageData);
MemoryStream ms = new MemoryStream(imageBytes, 0,
imageBytes.Length);
ms.Write(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(ms, true);
image.Save(#"D:\tmpImage.jpg");
The code above takes the Base64 type string and converts back into an image. This is written in C#.
With such an incomplete code example and such a vague problem description, it's difficult to know for sure what the problem is.
However, reviewing the code you did post, I see one bug that would be significant if this is really the code you are using. In your Java methodConvertion() method, you have this statement:
data = output.toByteArray();
The problem is that all that does is create a new byte[] object and assign the reference to your local variable named data. That object never leaves the method.
Presumably you have some other code which, after calling methodConvertion(), sends the byte[] object that is referenced by the argument you passed to that method. But that object is just going to be whatever it was before you called the method.
You should instead change your Java code so that it looks like this:
public static byte[] methodConvertion(){
File inputFile = new File("/storage/emulated/0/IFSpictures/icon-si_strapclamp.jpg");
try{
FileInputStream input = new FileInputStream(inputFile);
ByteArrayOutputStream output = new ByteArrayOutputStream ();
byte [] buffer = new byte [65536];
int l;
while ((l = input.read(buffer)) > 0)
output.write (buffer, 0, l);
input.close();
output.close();
return output.toByteArray();
} catch (IOException e) {
System.err.println(e);
return null;
}
}
And then in the caller, you should check the return value and only proceed if the value is not null, reporting the error somehow otherwise.
If that doesn't address your question, you should edit the question so that it has a better code example, and so that you are much more specific about what's wrong. What happens when you run the code, and how is that different from what you expected? Be sure to clearly state any error messages, quoting them exactly, and including any stack traces from exceptions.

C# , convert gif data to binary array to image

this is related with test instrument but need to more help in C# code.
i did more explain here about my question.
i send command to instrument and i just receive data from instrument.
received data is real format (binary) and i just put in to string variable.
here i captured what's inside in string..
http://i.stack.imgur.com/UcYqV.png
then what i want do is i want this string to convert byte array. because my goal is make png file in my pc. instrument manual said this returned data is gif format but returned real type.'
i believe the problem point is when i convert to byte array,,, there are problem...
does anyone has this kind of experiance,.????
/// below is just send command to instrument that i want " Returns an image of the display in .gif format "
my6705B.WriteString("hcop:sdump:data?", true);
string image_format = my6705B.ReadString();
/// what's inside string image_format ??![i attached screenshot png file. this is what i received from instrument. (manual said this is Returns an image of the display in .gif format)][1] ![png file][2]
http://i.stack.imgur.com/UcYqV.png
/// now here i think i did something wrong,
/// the goal is i want change this return data to gif or png or image file.
/// any solution is ok for me
/// i just try that change this data to byte array and then try to change image file.
/// i think some error here because my code success to convert byte array then create image,,, error
//// i believe that i did something wrong in convert byte array.....
System.Text.UnicodeEncoding encode = new System.Text.UnicodeEncoding();
byte[] byte_array22 = encode.GetBytes(image_format);
MemoryStream ms4 = new MemoryStream(byte_array22);
Image image = Image.FromStream(ms4); //// error point
image.Save(#"C:\Users\Administrator\Desktop\imageTest.png");
i believe that my explain is in comment.
let me explain again that my goal is convert gif data to image file.
instrument give us Returns an image of the display in .gif format.
i received this data to string array. < i dont know this is correct or not but for now i put to string array > then i just want to png or jpg file with this gif data.
please advice,.
Joseph Choi
Please Try ImageFormat Like
image.Save(#"C:\Users\Administrator\Desktop\imageTest.png", System.Drawing.Imaging.ImageFormat.Png);
Update:
byte[] byte_array22 = Encoding.Unicode.GetBytes(image_format);
MemoryStream ms4 = new MemoryStream(byte_array22);
Image image = Image.FromStream(ms4, true, true);
image.Save(#"C:\Users\Administrator\Desktop\imageTest.png",System.Drawing.Imaging.ImageFormat.Png);
Hmm ... here are a couple of methods to transform an image to Base64 format (string), and back.
private string ImageToBase64(Image image, System.Drawing.Imaging.ImageFormat format)
{
using (MemoryStream ms = new MemoryStream())
{
// Convert Image to byte[]
image.Save(ms, format);
byte[] imageBytes = ms.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
}
private 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);
return image;
}
}
You can use them and play with them to see if they suit you.
I'm not sure that taking an image and simply dumping it into string array will help you much.

Categories

Resources