I have a div with an image inside of it. In javascript I am getting the div, and sending the innerHTML of the div to the server. The javascript is oversimplified below:
function uploadImage() {
var imageInfo = document.getElementById('divImage').innerHTML;
PageMethods.uploadImage(imageInfo, onSuccess, onError);
} //end function
I am currently receiving this on the server as a string.
[WebMethod]
public static string uploadImage(string base64FileString){...}
The results are as follows:
<img height="150" width="150" title="name.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA...../>
I need to save this image to disk, and I'm at a loss. It's my understanding that I could get everything past the "base64," (using a split) and create an image using the following:
// Convert Base64 String to byte[]
byte[] imageBytes = Convert.FromBase64String(base64FileString);
MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
System.Drawing.Image image = System.Drawing.Image.FromStream(ms, true);
image.Save(.....);
But this seems very inefficient. Is there a better way to create the image from the string, a better way to receive the string, or better way to pass the string?
You can use File.WriteAllBytes:
byte[] imageBytes = Convert.FromBase64String(base64FileString);
File.WriteAllBytes(path, imageBytes);
Absolutely no need to go through MemoryStream and the System.Drawing namespace once you have the byte[].
I know there must be a better way to do this, but I have a solution that at least works. If anyone can point out a more sophisticated way I'm all ears. I would have assumed there was some sort of object that would receive the img on the server to save to disk, but maybe not.
Javascript and webmethod remain unchanged. I passed the InnerHTML of the div to the server, and accept it as a string. On the server I used multiple splits (which I understand to be very slow) to get at the base64 part of the image.
[WebMethod]
public static string uploadImage(string base64FileString){
//Get all of the text right of the comma
string base64PartTemp= base64FileString.Split(',')[1];
//The final part of the base64 had a \" to remove
//Now base64PartFinal is the base64 part of the image only
string base64PartFinal= base64PartTemp.Split('\"')[0];
//Get all of the text to the right of the period from original string
string fileTypePart = base64FileString.Split('.')[1];
//Because the file is an image the file type will be 3 chars
string fileType = fileTypePart.Substring(0, 3);
//Use a new guid for the file name, and append the fileType
string finalFileName = Guid.NewGuid() + "." + fileType;
//Turn the final base64 part into byte array
byte[] imageBytes = Convert.FromBase64String(base64PartFinal);
//Get the working directory of the project to store the files
string path= System.AppDomain.CurrentDomain.BaseDirectory.ToString();
//Append that I want to put the image in the images folder, under a designated filename
path += "Images/" + finalFileName;
//Write the image to file
File.WriteAllBytes(path, imageBytes);
...
}
I couldn't find an answer to this for a few days. I hope it helps someone. Like I said, may not be the most efficient solution, but it does work.
Related
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
I am new to C# and I'm really having a trouble on finding a way to convert files(doc, xlsx, jpg, png, etc.) to base64.
So far, what I got is a way to retrieve the path using Directory.GetFiles()....but this is not the result I was expecting.
What I expected it to do is get the data of the files(not the path) and convert it to base64 so that I can display it on my front-end.
Any idea?
Try this:
foreach (string filePath in Directory.GetFiles(#"C:\directory"))
{
Byte[] bytes = File.ReadAllBytes(filePath);
String file = Convert.ToBase64String(bytes);
}
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;
}
}
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.
I have literally tried every possible way on this but apparently I just can't figure out the right one.
I am trying to upload images to the next-gen gallery that is installed on a wordpress blog. Everything about xml-rpc is working since I am able to do all other stuff with it.
The problem is that server returns an error saying the image is not a valid one. Which is quite obvious that the problem is about base64. However, for test purposes i copied and checked the base64 string and realized it is just right, it converts right to the image using an external base64 to image converter.
This is the line that submits the query.
result = categories.newImage(1, "admin", "password", newImage);
The struct for newImage is;
public struct imageI
{
public string name;
public string type;
public string bits;
public bool overwrite;
public int gallery;
public int image_id;
}
And this is how a new one is initialized, along with converting an image into base64
//Creating the image base64 string
string filename = "asd.jpg";
Image image1 = Image.FromFile(filename);
string base64 = ImageToBase64(image1, image1.RawFormat);
//for test purposes i copied and checked the base64 and it is just right, it converts right to the image using an external base64 to image converter.
Clipboard.SetText(base64);
//Creating a newImage
imageI newImage = default(imageI);
newImage.name = "newImage";
newImage.bits = base64;
newImage.gallery= 86;
And finally my method "ImageToBase64(Image, ImageFomat)";
public 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;
}
}
In case anybody bumps on this, I figured it out, on the line;
newImage.name = "newImage"; the file name should be the same with the one you are uploading, or at least it should have the same extension so that the function in xml-rpc file can resolve the extension and check if it's okay to upload or not.