How to send clicked picture over REST api in C# unity - c#

This is my code to capture the image of webcamTexture.
public void SavePhoto()
{
Debug.Log(Application.dataPath);
Texture2D photo = new Texture2D(camTexture.width, camTexture.height);
photo.SetPixels(camTexture.GetPixels());
photo.Apply();
//Encode to a PNG
byte[] bytes = photo.EncodeToJPG();
System.IO.File.WriteAllBytes(Application.dataPath + "/photo.png", bytes);
predictImage(bytes);
}
This is my code to send image to the api
public async void predictImage(byte[] bytes)
{
ByteArrayContent content = new ByteArrayContent(bytes);
var response = await client.PostAsync("http://74.235.83.70:80", content);
var responseString = await response.Content.ReadAsStringAsync();
Debug.Log(responseString);
}
This is sending image as byte array but I want to send image as image file. How can I do this? Actually, that api is of machine learning model for image classification.

You can use the built-in tools to encode a texture as a byte array:
https://docs.unity3d.com/ScriptReference/ImageConversion.EncodeToJPG.html

Related

Svg to base64 without third party libraries c#

I am trying to convert svg image URL to base 64, the problem is that i am limited and I can't use third party libraries in this project.
Is there any possible way to do that?
I've tried this but it did not work. Someone said that svg is a file not an image so DownloadData won't work right.
byte[] imageBytes;
string base64String = string.Empty;
using (WebClient wc = new WebClient())
{
imageBytes = wc.DownloadData(appSuggestion?.IconUri.AbsoluteUri);
base64String = Convert.ToBase64String(imageBytes);
}
Any Idea what can I do?
Edit:
I wanted to use it in a data url "data:image/svg+xml;base64,[base64String]" in adaptive cards as an image url, at first I thought that adaptive cards are not supporting svg, but then I tried to write the url on chrome and it also didn't show the image.
Using DownloadData is perfectly valid here as it will return the content of the URI returned by the server as byte[]. The base64 conversion is also correct. What you've got so far will give you the base64-encoded content of any URI. I've just tested this and it works correctly.
Here's my test code to produce a data: URI from an SVG file hosted on a remote web server:
public string SVGUriToDataUri(Uri src)
{
using (var wc = new System.Net.WebClient())
{
var imageBytes = wc.DownloadData(src);
var imageBase64 = Convert.ToBase64String(imageBytes);
return "data:image/svg+xml;base64," + {imageBase64};
}
}
Putting the output of that into the address bar in Chrome displays the image as expected.
Here's a more general version that gets the mime type from the server:
public string DownloadAsDataUri(Uri src)
{
using (var wc = new System.Net.WebClient())
{
var imageBytes = wc.DownloadData(src);
var imageBase64 = Convert.ToBase64String(imageBytes);
var mimeType = wc.ResponseHeaders["content-type"];
if (mimeType.Contains(';'))
mimeType = mimeType.Split(';')[0];
return $"data:{mimeType};base64,{imageBase64}";
}
}
If it's a PNG, BMP, ICO or whatever and it works when you put the URI itself then this should work. It works for me with the image link you posted - which is SVG.
If this does not work for then please post a copy of the output so we can investigate. At this point the only other option I can think of is that appSuggestion?.IconUri.AbsoluteUri is not giving you the correct address.

How to assemble file from byte[] via HTTP request method C#

I want to send file as byte[] to another PC via HTTP POST method. What is the most efficient way to assemble the file from byte[] on the other side? I am using File.ReadAllBytes method to get byte[] from file.
If you are using tcp the network protocol will make sure that your stream is coming in the right order and without dropped parts. Therefore, the simplest readstream will be the most efficient. If you want to use parallel routes and play with the datagrams.
If the file is large you will have to transmit and receive it in chunks. But the IP streams can hide that from you.
For example: https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.getstream?view=netframework-4.7.2
This is what worked for me. I used this method to call api method and send file as byte[]. I tried sending whole byte[] but api method wasn't able to recive it.
private static async void SendFiles(string path)
{
var bytes = File.ReadAllBytes(path);
var length = bytes.Length;
foreach (var b in bytes)
{
length--;
string sendFilesUrl = $"http://api/communication/sendF/{b}/{length}";
StringContent queryString = new StringContent(bytes.ToString(), Encoding.UTF8, "application/x-www-form-urlencoded");
HttpResponseMessage response = await client.PostAsync(sendFilesUrl, queryString);
string responseBody = await response.Content.ReadAsStringAsync();
}
}
My api method is
[HttpPost]
[Route("sendF/{b}/{length}")]
public HttpResponseMessage SendF([FromUri]byte[] b, [FromUri]int length)
{
if(length != 0)
{
bytes.AddRange(b);
}
else
{
File.WriteAllBytes(#"G:\test\test.exe", bytes.ToArray<byte>());
}
return CreateResponse(client);
}
This code works for me but it takes very long to pass all bytes if the file is large. Currently I'm searching for more efficient way of sending bytes. One solution that came to my mind is to send byte[] in chunks

C# Resize bitmap image before decoder operations

I'm attempting to create a small OCR application where I can select words. I have already implemented this using the Microsoft example:
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
// Load image from install folder.
var file = await Package.Current.InstalledLocation.GetFileAsync("photo.png");
using (var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
// Create image decoder.
var decoder = await BitmapDecoder.CreateAsync(stream);
// Load bitmap.
var bitmap = await decoder.GetSoftwareBitmapAsync();
// Extract text from image.
OcrResult result = await ocrEngine.RecognizeAsync(bitmap);
// Display recognized text.
OcrText.Text = result.Text;
}
}
However, I want the loaded image to fit to the screen, I do this by simply creating a BitmapImage, setting its source to the stream and applying the source of an Image element to the bitmap. This problem with this, is that coords of the OCR words are not aligned to the image, as I presume the bitmap created from the decoder uses the original image size. How can I rectify this issue, so that the size of the image the OCR engine uses is the same as Image element?
My code to get the image, and to get an OCR result from:
// Create a stream from the picked file
IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);
// Create a bitmap from the stream
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(stream);
this.imgDisplay.Source = bitmap;
// Create the decoder from the stream
var decoder = await BitmapDecoder.CreateAsync(stream);
// Get the SoftwareBitmap representation of the file
SoftwareBitmap sBitmap = await decoder.GetSoftwareBitmapAsync();
mOcrResult = await mOcrEngine.RecognizeAsync(sBitmap);

MVC providing runtime image not save on disk to browser

My MVC app creates images at runtime that I do NOT need to save on the disk.
What's the best way to send those to the requesting browser?
Note that the images will never be the same, so there is no reason to save them on disk first.
The server will draw the random image and will return the image to the calling client. I'm trying to understand what the best format for this type of operation is (bitmap, image ...) so that the streaming back to the server is as smooth and as fast as possible.
If you are sending them in the same page where you create it, then you can modify your Response to send it directly.
//After having your bitmap created...
MemoryStream ms = new MemoryStream();
bmp.Save(ms, ImageFormat.PNG);
bmp.Dispose();
byte[] data = ms.ToArray();
Response.ContentType = "image/png";
Response.ContentLength = data.Length;
using(var str = Response.GetResponseStream())
str.Write(data, 0, data.Length);
Response.End();
If you can get the bytes of the bitmap, then it's easy to return it to the client
public ActionResult GetImage()
{
byte[] byteArray = MagicMethodToGetImageData();
return new FileContentResult(byteArray, "image/jpeg");
}
Moreover, if you want to return the image plus some data, you can encode the bytes as base64 and wrap it in a JSON like this:
public ActionResult GetImage()
{
byte[] byteArray = MagicMethodToGetImageData();
var results = new
{
Image = Convert.ToBase64String(byteArray),
OtherData = "some data"
};
return Json(results);
}
One possibility would be to use the FileContentResult class to read the file content and directly show it or offer to download. A solution could look like this:
private FileContentResult getFileContentResult(string name, bool download = true)
{
if (!string.IsNullOrEmpty(name))
{
// don't forget to set the appropriate image MIME type
var result = new FileContentResult(System.IO.File.ReadAllBytes(name), "image/png");
if (download)
{
result.FileDownloadName = Server.UrlEncode(name);
}
return result;
}
return null;
}
The use this method in some Action like this:
public ActionResult GetImage(string name)
{
return getFileContentResult(name, true);
// or use the image directly for example in a HTML img tag
// return getFileContentResult(name);
}
The class is pretty robust and fast - I have made good experience using it for exactly the same purpose.

Disallowed key characters while uploading image in base64 format

I'm developing Windows phone(8.0)apps and I'm new to it,I'm using below code to post image to server in Base64 format using post client
Uri uri = new Uri(UPLOAD_IMAGE_PATH);
UploadImageData requestData = new UploadImageData();
requestData.image = base64String;
string jsonString = JsonConvert.SerializeObject(requestData);
PostClient proxy = new PostClient(jsonString);
proxy.DownloadStringCompleted += new PostClient.DownloadStringCompletedHandler(proxy_DownloadStringCompleted);
proxy.DownloadStringAsync(uri);
where base64String is my image string encoded in Bae64 by using below code
internal static string ImageToBase64String(Stream choosenPhoto,Image image)
{
WriteableBitmap bmp = new WriteableBitmap((BitmapSource)image.Source);
byte[] byteArray;
using (MemoryStream stream = new MemoryStream())
{
bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
byteArray = stream.ToArray();
return Convert.ToBase64String(byteArray);
}
}
In below response it returns "disallowed key charaters" on result.
void proxy_DownloadStringCompleted(object sender, WindowsPhonePostClient.DownloadStringCompletedEventArgs e)
{
string result = e.Result;
}
But when i post same JSON string using REST Client from Mozilla, JSON response from server is successfull.
I searched about this and i got some links link 1, link 2 that i need to allow characters on server side in Input.php file, So exactly what kind of character i need to allow. It works from REST Client did i miss something in my C# code, Please help me
It doesn't seem to explicitly mention the Base64 string (unless I'm missing something, having never developed for a WinPhone OS). Have you checked the URL that you're sending a POST request to?

Categories