I am trying to load an image as a base 64 string so that i can show it in a html like this:
<html><body><img src="data:image/jpeg;base64,/></img></body></html>
Heres my code so far, but it does not really work:
public async static Task<string> getImage(string url)
{
var request = (HttpWebRequest)WebRequest.Create(url);
request.Accept = "data:image/jpg;charset=base64";
request.Credentials = new NetworkCredential(user, pw);
using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null)))
{
StreamReader sr = new StreamReader(response.GetResponseStream());
return sr.ReadToEnd();
}
I tried using this method i found elsewhere to encode the return-String as base64, but when placing it in a html the image just shows the typical placeholder.
public static string Base64Encode(string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}
EDIT:
Here is how the html looks:
It seems to me that you need to separate the base64 part, which is only needed in your HTML, from fetching the data from the response. Just fetch the data from the URL as binary data and convert that to base64. Using HttpClient makes this simple:
public async static Task<string> GetImageAsBase64Url(string url)
{
var credentials = new NetworkCredential(user, pw);
using (var handler = new HttpClientHandler { Credentials = credentials })
using (var client = new HttpClient(handler))
{
var bytes = await client.GetByteArrayAsync(url);
return "image/jpeg;base64," + Convert.ToBase64String(bytes);
}
}
This assumes the image always will be a JPEG. If it could sometimes be a different content type, you may well want to fetch the response as an HttpResponse and use that to propagate the content type.
I suspect you may want to add caching here as well :)
using (HttpClient client = new HttpClient())
{
try
{
using (Stream stream = await client.GetStreamAsync(uri))
{
if (stream == null)
return (Picture)null;
byte[] buffer = new byte[16384];
using (MemoryStream ms = new MemoryStream())
{
while (true)
{
int num = await stream.ReadAsync(buffer, 0, buffer.Length, cancellation);
int read;
if ((read = num) > 0)
ms.Write(buffer, 0, read);
else
break;
}
imageData = Convert.ToBase64String(ms.ToArray());
}
buffer = (byte[])null;
}
}
catch (Exception ex)
{
}
}
You must first get the image from disk, then convert it to byte[] and then again to base64.
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;
}
}
Related
I tried to convert my image from camera to byte[] and then make request to my server but it is not working so my image from camera is
var image = textureView.Bitmap;
image = Android.Graphics.Bitmap.CreateBitmap
(image,
(int)OCR_Rectangle.GetX(),
(int)OCR_Rectangle.GetY(),
OCR_Rectangle.Width,
OCR_Rectangle.Height);
My web request is
public async static Task<string> ParseAsync(byte[] image)
{
string id = "my id ";
string apiKey = "my api key ";
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("app_id", id);
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("app_key", apiKey);
var base64 = Convert.ToBase64String(image);
var imageUri = "data:image/jpg;base64," + base64;
var json = JsonConvert.SerializeObject(new { src = imageUri });
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync("my website", content);
var dynObj = JsonConvert.DeserializeObject<RootObjectLatex>(await response.Content.ReadAsStringAsync());
return dynObj.latex;
}
}
Here is my attempt to convert bitmap to byte[]
byte[] bitmapData;
using (var stream = new MemoryStream())
{
image.Compress(Bitmap.CompressFormat.Png, 0, stream);
bitmapData = stream.ToArray();
}
And then i want to use bitmapData in my request.But no luck.
So, I found error this works
byte[] bitmapData;
using (var stream = new MemoryStream())
{
image.Compress(Bitmap.CompressFormat.Png, 0, stream);
bitmapData = stream.ToArray();
}
but i type wrong api key in my request
I have a requirement to post binary file of size 100MB data in the format of either JSON or byte array to Web API 1.1.
My client application is C# winforms application with x32 bit architecture. Where as I want to perform reading binary file from this client application and send this binary file byte array to Web API.
Current implementation in my winforms application is as below
var sFile = #"C"\binary.zip";
var mybytearray = File.ReadAllBytes(sFile);
var webRequest =
(HttpWebRequest)WebRequest.Create("http://localhost/filewriter");
webRequest.ContentType = "text/plain";
webRequest.Method = WebRequestMethods.Http.Post;
webRequest.AllowWriteStreamBuffering = true;
webRequest.Timeout = 100000;
webRequest.Headers.Add("fileName", Path.GetFileName(sFile));
webRequest.ContentLength = mybytearray.Length;
using (var dataStream = new StreamWriter(webRequest.GetRequestStream()))
dataStream.Write(mybytearray);
using (var response = webRequest.GetResponse())
{
if(response.StatusCode = HttpStatusCode.Ok;
return true;
}
below is written at my Web api method
[HttpPost]
public HttpResponseMessage filewriter(byte[] binaryData)
{
using (FileStream binaryFileStream = new FileStream("C:\\myNewFile.zip", FileMode.Create, FileAccess.ReadWrite))
{
binaryFileStream.Write(binaryData, 0, binaryData.Length);
}
}
As you can see, in above code I was not able to send byte array to web api method filewriter. Am I missing something that should work in this case.
Other way as I said I was tried same but instead of byte array with Json one as below
var sFile = #"C"\binary.zip";
var mybytearray = File.ReadAllBytes(sFile);
var mymodel = new model
{
fileName = sFile,
binaryData = mybytearray
};
var jsonResendObjects = JsonConvert.SerializeObject(mymodel);
var webRequest = (HttpWebRequest)WebRequest.Create("http://localhost/filewriter");
webRequest.ContentType = "application/json";
webRequest.Method = WebRequestMethods.Http.Post;
webRequest.AllowWriteStreamBuffering = true;
webRequest.Timeout = 100000;
webRequest.Headers.Add("fileName", Path.GetFileName(sFile));
webRequest.ContentLength = jsonResendObjects.Length;
byte[] responseData = null;
webRequest.AllowWriteStreamBuffering = true;
using (var dataStream = new StreamWriter(webRequest.GetRequestStream()))
dataStream.Write(jsonResendObjects);
On web api side
[HttpPost]
public HttpResponseMessage filewriter([FromBody]model mymodel)
{
using (FileStream binaryFileStream = new FileStream("C:\\myNewFile.zip", FileMode.Create, FileAccess.ReadWrite))
{
binaryFileStream.Write(mymodel.binarydata, 0, binaryDatabinarydat.Length);
}
}
According to me, it would be easy to use base64 encoding for
communication.
If you want to do so
First, convert your file to byte[] and then to base64 string
Like this:
byte[] bytes = File.ReadAllBytes("path");
string file = Convert.ToBase64String(bytes);
// You have base64 Data in "file" variable
On your WebAPI Endpoint accept string
[HttpPost]
public HttpResponseMessage filewriter(string fileData)
{
}
Then convert your base64 string back to byte[] and write it to file or whatever you want to do with that.
Like This:
// put your base64 string in b64str
Byte[] bytes = Convert.FromBase64String(b64Str);
File.WriteAllBytes(path, bytes);
And you can Compress your string Using GZIP Like this
public static void CopyTo(Stream src, Stream dest) {
byte[] bytes = new byte[4096];
int cnt;
while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0) {
dest.Write(bytes, 0, cnt);
}
}
public static byte[] Zip(string str) {
var bytes = Encoding.UTF8.GetBytes(str);
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream()) {
using (var gs = new GZipStream(mso, CompressionMode.Compress)) {
//msi.CopyTo(gs);
CopyTo(msi, gs);
}
return mso.ToArray();
}
}
public static string Unzip(byte[] bytes) {
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream()) {
using (var gs = new GZipStream(msi, CompressionMode.Decompress)) {
//gs.CopyTo(mso);
CopyTo(gs, mso);
}
return Encoding.UTF8.GetString(mso.ToArray());
}
}
Reference:-
Convert file to base64 and back
GZip Compression
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;
}
}
}
I am trying to do this using C#(Winforms).
The code I am using is giving me a string as an output, but I need to have a zipped file.
I am using the following code
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(
"ftp:SITENAME/FILENAME.zip");
request.Method = WebRequestMethods.Ftp.DownloadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential("", "");
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
//StreamWriter writer = new StreamWriter(responseStream);
MessageBox.Show(reader.ReadtoEnd);
MessageBox.Show("Download Complete, status {0}" + response.StatusCode);
reader.Close();
response.Close();
}
catch (NotSupportedException ne)
{
MessageBox.Show(ne.Message);
}
I have an idea that I have to use Open source library from SharpZipLib to convert this string to a zipped file. But,I cannot find any sample code to show me how to do that.
I would really appreciate if someone can guide me through the process.
Thanks,
Sidhanshu
This might do just that.
using ICSharpCode.SharpZipLib.BZip2;
public static string Unzip(byte[] compressedbytes)
{
string result;
MemoryStream m_msBZip2 = null;
BZip2InputStream m_isBZip2 = null;
m_msBZip2 = new MemoryStream(compressedbytes);
// read final uncompressed string size stored in first 4 bytes
using (BinaryReader reader = new BinaryReader(m_msBZip2, System.Text.Encoding.ASCII))
{
Int32 size = reader.ReadInt32();
m_isBZip2 = new BZip2InputStream(m_msBZip2);
byte[] bytesUncompressed = new byte[size];
m_isBZip2.Read(bytesUncompressed, 0, bytesUncompressed.Length);
m_isBZip2.Close();
m_msBZip2.Close();
result = Encoding.ASCII.GetString(bytesUncompressed, 0, bytesUncompressed.Length);
reader.Close();
}
return result;
}
public static byte[] Zip(string sBuffer)
{
byte[] result;
using (MemoryStream m_msBZip2 = new MemoryStream())
{
Int32 size = sBuffer.Length;
// Prepend the compressed data with the length of the uncompressed data (firs 4 bytes)
using (BinaryWriter writer = new BinaryWriter(m_msBZip2, System.Text.Encoding.ASCII))
{
writer.Write(size);
using (BZip2OutputStream m_osBZip2 = new BZip2OutputStream(m_msBZip2))
{
m_osBZip2.Write(Encoding.ASCII.GetBytes(sBuffer), 0, sBuffer.Length);
m_osBZip2.Close();
}
writer.Close();
result = m_msBZip2.ToArray();
m_msBZip2.Close();
}
}
return result;
}
I'm trying to use a local c# app to pull some images off a website to files on my local machine. I'm using the code listed below. I've tried both ASCII encoding and UTF8 encoding but the final file is not an correct. Does anyone see what I'm doing wrong? The url is active and correct and show the image just fine when I put the address in my browser.
private void button1_Click(object sender, EventArgs e)
{
HttpWebRequest lxRequest = (HttpWebRequest)WebRequest.Create("http://www.productimageswebsite.com/images/stock_jpgs/34891.jpg");
// returned values are returned as a stream, then read into a string
String lsResponse = string.Empty;
HttpWebResponse lxResponse = (HttpWebResponse)lxRequest.GetResponse();
using (StreamReader lxResponseStream = new StreamReader(lxResponse.GetResponseStream()))
{
lsResponse = lxResponseStream.ReadToEnd();
lxResponseStream.Close();
}
byte[] lnByte = System.Text.UTF8Encoding.UTF8.GetBytes(lsResponse);
System.IO.FileStream lxFS = new FileStream("34891.jpg", FileMode.Create);
lxFS.Write(lnByte, 0, lnByte.Length);
lxFS.Close();
MessageBox.Show("done");
}
nice image :D
try using the following code:
you needed to use a BinaryReader, 'cause an image file is binary data and thus not encoded in UTF or ASCII
edit: using'ified
HttpWebRequest lxRequest = (HttpWebRequest)WebRequest.Create(
"http://www.productimageswebsite.com/images/stock_jpgs/34891.jpg");
// returned values are returned as a stream, then read into a string
String lsResponse = string.Empty;
using (HttpWebResponse lxResponse = (HttpWebResponse)lxRequest.GetResponse()){
using (BinaryReader reader = new BinaryReader(lxResponse.GetResponseStream())) {
Byte[] lnByte = reader.ReadBytes(1 * 1024 * 1024 * 10);
using (FileStream lxFS = new FileStream("34891.jpg", FileMode.Create)) {
lxFS.Write(lnByte, 0, lnByte.Length);
}
}
}
MessageBox.Show("done");
Okay, here's the final answer. It uses a memorystream as a way to buffer the data from the reaponsestream.
private void button1_Click(object sender, EventArgs e)
{
byte[] lnBuffer;
byte[] lnFile;
HttpWebRequest lxRequest = (HttpWebRequest)WebRequest.Create("http://www.productimageswebsite.com/images/stock_jpgs/34891.jpg");
using (HttpWebResponse lxResponse = (HttpWebResponse)lxRequest.GetResponse())
{
using (BinaryReader lxBR = new BinaryReader(lxResponse.GetResponseStream()))
{
using (MemoryStream lxMS = new MemoryStream())
{
lnBuffer = lxBR.ReadBytes(1024);
while (lnBuffer.Length > 0)
{
lxMS.Write(lnBuffer, 0, lnBuffer.Length);
lnBuffer = lxBR.ReadBytes(1024);
}
lnFile = new byte[(int)lxMS.Length];
lxMS.Position = 0;
lxMS.Read(lnFile, 0, lnFile.Length);
}
}
}
using (System.IO.FileStream lxFS = new FileStream("34891.jpg", FileMode.Create))
{
lxFS.Write(lnFile, 0, lnFile.Length);
}
MessageBox.Show("done");
}
A variation of the answer, using async await for async file I/O. See Async File I/O on why this is important.
Download png and write to disk using BinaryReader/Writer
string outFile = System.IO.Path.Combine(outDir, fileName);
// Download file
var request = (HttpWebRequest) WebRequest.Create(imageUrl);
using (var response = await request.GetResponseAsync()){
using (var reader = new BinaryReader(response.GetResponseStream())) {
// Read file
Byte[] bytes = async reader.ReadAllBytes();
// Write to local folder
using (var fs = new FileStream(outFile, FileMode.Create)) {
await fs.WriteAsync(bytes, 0, bytes.Length);
}
}
}
Read all bytes extension method
public static class Extensions {
public static async Task<byte[]> ReadAllBytes(this BinaryReader reader)
{
const int bufferSize = 4096;
using (var ms = new MemoryStream())
{
byte[] buffer = new byte[bufferSize];
int count;
while ((count = reader.Read(buffer, 0, buffer.Length)) != 0) {
await ms.WriteAsync(buffer, 0, count);
}
return ms.ToArray();
}
}
}
You can use the following method to download an image from a web site and save it, using the Image class:
WebRequest req = WebRequest.Create(imageUrl);
WebResponse resp = req.GetResponse();
Image img = Image.FromStream(resp.GetResponseStream());
img.Save(filePath + fileName + ".jpg");