Sending Image in Base64 String and receiving in webservice via kSoap - c#

i am sending an image in byte[] and 3 strings to a webservice usingksoap but its not working for me , i am not sure where i am wrong, in sending image from Android and at receiving end, i am putting the code here kindly check it
Here is how i am converting image to byte[] at client (Android) side
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
and here is the code where i am sending it to webservice via Ksoap
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("Name", name);
request.addProperty("Email", email);
request.addProperty("Picture", encoded );
request.addProperty("Date", date);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport. call(SOAP_ACTION, envelope);
SoapPrimitive result = (SoapPrimitive) envelope.getResponse();
String str = result.toString();
and here is the webMethod where i am receiving this soap envelop
[WebMethod]
public String PutFile(String Name, String Email, String Picture, String Date)
{
String PictureByteString = Picture;
Image imgFromString = SaveByteArrayAsImage(PictureByteString);
DateTime.Now.ToShortDateString() + ".jpg"));
string serverpath = Server.MapPath("~/" + Email + "-" + DateTime.Now.ToShortDateString());
imgFromString.Save(serverpath, System.Drawing.Imaging.ImageFormat.Jpeg);
String Path = serverpath + ".Jpeg";
return Name;
}
private Image SaveByteArrayAsImage(string base64String)
{
byte[] bytes = Convert.FromBase64String(base64String);
image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = Image.FromStream(ms);
}
return image;
}
when i send data to webservice android LogCat shows me
java.io.IOException: HTTP request failed, HTTP status: 500
i think so which means that the data i am sending to webservice is not of correct type, so i tried to make String Picture to byte[] Picture in webmethod but result was same. I am not being able to figure out where i am wrong ...
Update:
now sending image in a Base64 string and java exception is gone but the webmethod is still not converting that Base64 string into image...

This is how i did it.
parameter passed to function is Base64 string
public string SendImage(string data)
{
byte[] myarray = Convert.FromBase64String(data);
MemoryStream memStream = new MemoryStream(myarray);
Image myimage = Image.FromStream(memStream);
myimage.Save("G:\\image.png", ImageFormat.Png);
return "succeeded";
}
This is working perfectly for me, Hope it helps.

Related

store byte[] into file C#

I have this function reading website names one at a time and creating an object array for each url where the website name and bytes received from the webpage is saved into the array. This array is then saved into a txt file called "saveData.txt"
string[] readText = File.ReadAllLines("new.txt");
foreach (string s in readText)
{
object[] url = new object[2];
url[0] = s;
url[1] = displayByteCode(s);
using (StreamWriter writer = new StreamWriter("saveData.txt",true))
{
writer.WriteLine(url[0]+" "+ url[1]);
}
}
The displayByteCode is a function that is as follows:
public byte[] displayByteCode(string getURLCode)
{
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(getURLCode);
myRequest.Method = "GET";
WebResponse myResponse = myRequest.GetResponse();
MemoryStream ms = new MemoryStream();
myResponse.GetResponseStream().CopyTo(ms);
byte[] data = ms.ToArray();
return data;
}
it is to return the bytes received from the website. While the url is saved properly. the byte is saved as "System.Byte[]" how do i save the actually byte instead of this? Thank you for your help!
when you call + operator on a string and an object, it calls toStirng method on that object (this is why it writes System.Byte[] on file)
you can't write both string and bytes in c#, for storing bytes, you can use :
File.WriteAllBytes("saveData.txt", (byte[])url[1]);
or you can convert it to string and store it :
writer.WriteLine(url[0]+" "+ Convert.ToBase64String((byte[])url[1]));

Server for displaying pictures in web browser

What I am trying to do is send a picture from the server to the client (web browser). So when I open the link in the browser, for example https://localhost:8080/geoserver/ (I set the port to 8080 at the beginning) it will display the message "hello world" which is fine but now I am trying to send image with the StreamWriter and all I got was some text like System.Drawing.Bitmap and there was no picture displayed in the browser. Im working with c# console application.
My code:
static void Main(string[] args)
{
HttpListener listen = new HttpListener();
string url = "http://localhost";
string port = "";
Console.Write("Nastavite port:");
port = Console.ReadLine();
url = url + ":" + port + "/geoserver/";
listen.Prefixes.Add(url);
listen.Start();
while (true)
{
Console.WriteLine("Cakam...");
HttpListenerContext kontekst = listen.GetContext();
string msg = "hello world";
kontekst.Response.ContentLength64 = Encoding.UTF8.GetByteCount(msg);
kontekst.Response.StatusCode = (int)HttpStatusCode.OK;
using(Stream stream = kontekst.Response.OutputStream)
{
using(StreamWriter writer = new StreamWriter(stream))
{
writer.Write(msg);
}
}
Console.WriteLine("Sporočilo poslano");
}
}
You can do it, by converting the image to base64 and display it in a html img tag.
1) Use the System.Drawing library to get the picture as a byte array
Image image = Image.FromFile("test-img.jpg");
MemoryStream ms = new MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] imgBytes = ms.ToArray();
2) After you need to convert it to a base64 string
string base64 = Convert.ToBase64String(imgBytes);
3) Then you create the html response text
string html = $"<html><img src=\"data: image / png; base64, {base64} \"></html>";
4) Now you can write this text to the output stream
Stream stream = kontekst.Response.OutputStream;
StreamWriter writer = new StreamWriter(stream);
writer.WriteLine(html);
So the full working code looks like this
static void Main(string[] args)
{
HttpListener listen = new HttpListener();
string url = "http://localhost";
string port = "";
Console.Write("Nastavite port:");
port = Console.ReadLine();
url = url + ":" + port + "/geoserver/";
listen.Prefixes.Add(url);
listen.Start();
while (true)
{
Console.WriteLine("Cakam...");
HttpListenerContext kontekst = listen.GetContext();
kontekst.Response.StatusCode = (int)HttpStatusCode.OK;
using (Stream stream = kontekst.Response.OutputStream)
using (Image image = Image.FromFile("test-img.jpg"))
using (MemoryStream ms = new MemoryStream())
using (StreamWriter writer = new StreamWriter(stream))
{
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
string base64 = Convert.ToBase64String(ms.ToArray());
writer.WriteLine($"<html><img src=\"data: image / png; base64, {base64} \"></html>");
}
Console.WriteLine("Sporočilo poslano");
}
}
The minimal changes required to make your code work is to use the Save method to write the image to the stream, instead of Writer.Write(), which will call the ToString() of the object, (if it's not already a character array) resulting in sending the class name that you experienced.
//Can't set the response length upfront, if you really need to set it you need to
//calculate it from the size of the image.
//kontekst.Response.ContentLength64 = Encoding.UTF8.GetByteCount(msg);
//Most browsers figure it out without this, but good practice to set the type:
kontekst.Response.ContentType = "image/bmp";
kontekst.Response.StatusCode = (int)HttpStatusCode.OK;
var img = Image.FromFile(#"some.bmp");
using (Stream stream = kontekst.Response.OutputStream)
{
img.Save(stream, ImageFormat.Bmp);
}
I would also consider changing some other things:
Instead of System.Drawing.Bitmap, use System.Drawing.Image as I did if you don't need to edit the image on the server. Or even better, if you don't need to treat it as an image on the server side, just read it in with a FileStream and write it out to the Output stream.
Do you really want to implement your on server and deal with the low level HttpContext / listeners? Maybe you could use ASP.Net Core with Kestrel.

JSON parsing issue when using filepath as image url

I am having an issue getting my image to upload to the microsoft face api.
I have a function that posts to the server, which implements another function that turns a user selected image into a base64 encoded stream.
public async Task getImageID(){
//filedialogs, etc...
HttpResponseMessage response;
string responseBodyAsText;
byte[] byteData = Encoding.UTF8.GetBytes("{ \"url\":\""+baseEncodeImage(getPhoto.FileName)+" \"}");
using (var content = new ByteArrayContent(byteData)){
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
response = await client.PostAsync(uri, content);
responseBodyAsText = await response.Content.ReadAsStringAsync();
//debug prints
Console.Write(responseBodyAsText+"\n"+ getPhoto.FileName+"\n"+byteData);
}
}
public string baseEncodeImage(string filePath){
//This function will take the filepath selected from the filedialog
//and turn it into a base64 encoded stream to be used by the face api
using (Image image = Image.FromFile(filePath))
{
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
}
}
It posts to the server, and returns the following in the command line:
What do I need to manipulate so that it works with the base64 encoding? It was posting with an image url off the internet prior to the modifications.
I have found the solution. I converted the type returned from the encode function to a byte[] and simplified the process by making the byte[] the size of the image, and simply writing the binary data to memory. The calling function was further simplified by placing the call in the using statement and removing the original url formatting which wasnt needed.
// Request body
HttpResponseMessage response;
string responseBodyAsText;
using (var content = new ByteArrayContent((baseEncodeImage(getPhoto.FileName))))
{
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response = await client.PostAsync(uri, content);
responseBodyAsText = await response.Content.ReadAsStringAsync();
//debug prints
Console.Write(responseBodyAsText + "\n" + getPhoto.FileName + "\n");
}
}
public byte[] baseEncodeImage(string filePath){
//This function will take the filepath selected from the filedialog
//and turn it into a base64 encoded stream to be used by the face api
using (Image image = Image.FromFile(filePath))
{
using (MemoryStream m = new MemoryStream())
{
FileStream imgStream = File.OpenRead(filePath);
byte[] blob = new byte[imgStream.Length];
imgStream.Read(blob, 0, (int)imgStream.Length);
return blob;
}
}
}

Upload Image to a Chevereto Website C#

A friend of my is trying to upload a image on a Windows Form App to a chevereto website, using chevereto API and trying to get the link back(response from website), but its not really working...
API: Chevereto API
UPDATE: Code Added
static class Upload
{
string apiKey = "DEFAULT_API_KEY";
public string UploadImage(Image image)
{
WebClient webClient = new WebClient();
webClient.Headers.Add("key", apiKey);
webClient.Headers.Add("format", "txt");
System.Collections.Specialized.NameValueCollection Keys =
new System.Collections.Specialized.NameValueCollection();
try
{
string ht = "http://";
Keys.Add("image", ImageToBase64(image, ImageFormat.Bmp));
byte[] responseArray = webClient.UploadValues(ht + "mysite.com/api/1/upload/", Keys);
string result = Encoding.ASCII.GetString(responseArray);
return result;
}
catch (Exception e)
{
InternalConsole.LogError("Cannot upload image, error on next line: ");
InternalConsole.Log(e.Message);
return "none";
}
}
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;
}
}
}
Can someone show me how its done?
Thanks in advance.
Nevermind guys, my friend already fixed the problem.
He used WebRequest to send and receive the data.
He also said, dont forget to escape the string of base64(+, =, /), or the api will not accept properly and will return invalid base64 string.
Thanks anyway.

Google Apis V2 html mime/type

I upload doc,xls files but i dont understand how upload html files. This code upload file but dont preview file. Its say- "We apologize Preview not available". Whats mime type i must set ?
if (extension == ".htm" || extension == ".html")
{
File body = new File();
body.Title = Path.GetFileNameWithoutExtension(item);
//body.Description = "A test document";
body.MimeType = "text/HTML";
byte[] byteArray = System.IO.File.ReadAllBytes(item);
System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
FilesResource.InsertMediaUpload request = service.Files.Insert(body, stream,
"application/vnd.google-apps.file");
request.Convert = true;
I had some problems uploading files using the Gmail API. I don't know if the Files API works the same but, you could try encoding the byteArray before you call the Insert method. Implement these methods:
protected static string Base64ForUrlEncode(string str)
{
StringBuilder result = new StringBuilder(Convert.ToBase64String(Encoding.ASCII.GetBytes(str)).TrimEnd('='));
result.Replace('+', '-');
result.Replace('/', '_');
return result.ToString();
}
protected static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
Then, call it before the Insert method:
byte[] byteArray = System.IO.File.ReadAllBytes(item);
string base64 = Base64ForUrlEncode(System.Text.Encoding.UTF8.GetString(byteArray));
System.IO.MemoryStream stream = new System.IO.MemoryStream(GetBytes(base64));
FilesResource.InsertMediaUpload request = service.Files.Insert(body, stream, "application/vnd.google-apps.file");
You could also try to set the mime type to "text/html", in lowercase letters.

Categories