Reputation: 40
I have created something like this: https://www.codeproject.com/Tips/485182/Create-a-local-server-in-Csharp
But the tutorial only shows how to send a string. But when I try to modify the code by adding an img src
, it won't show up. This is what I have done so far:
private void sendData(int total, DataGridView dgv, Image v)
{
Thread t = new Thread(() => ResponseThread(total, dgv,v));
t.Start();
}
private void ResponseThread(int t, DataGridView dgv, Image u)
{
String table="";
HttpListenerContext context = _httpListener.GetContext();
for (int i = 0; i < t; i++)
table += "<tr><td>" + dgv.Rows[i].Cells[0].Value.ToString() + "</td><td>" + dgv.Rows[i].Cells[1].Value.ToString() + "</td><td>" +
dgv.Rows[i].Cells[2].Value.ToString() + "</td><td>" + dgv.Rows[i].Cells[3].Value.ToString() + "</td><td>" + dgv.Rows[i].Cells[4].Value.ToString() +
"</td><td>" + dgv.Rows[i].Cells[5].Value.ToString() + "</td></tr>";
byte[] _responseArray = Encoding.UTF8.GetBytes(
"<html>" +
"<head>" +
"<title>Hello</title>" +
"</head>" +
"<body>" +
"<h1>Total: " + t +
"<table style=\"width:100%\"> <tr><b><th>No</th><th>Centroid X</th><th>Centroid Y</th><th>Orientation</th><th>Area</th><th>Area (mm)</th></b></tr>"+
table+"</table>"+
"<img src="+u+"></img>"+
"<p><i>Last Update: " + DateTime.Now.ToShortDateString() + " "+DateTime.Now.ToLongTimeString()+
"</i></p>" +
"</h1></body></html>");
context.Response.OutputStream.Write(_responseArray, 0, _responseArray.Length);
context.Response.KeepAlive = true;
context.Response.Close();
}
Upvotes: 0
Views: 1349
Reputation: 5107
You're on the right track, but you need to handle the bytes of the Image
separately. Once the browser gets your response data, it needs to be able to understand how to read the image. <img src="+u+"></img>
is not sufficient.
Most of the time, browsers will get a URL in the src
attribute, and the image file is downloaded and displayed as-is. In your case, the image bytes need to be embedded in the response, but in a safe way so they can be transmitted and unpacked. Thankfully, this is possible via base-64 embedding. The data should take the form data:image/png;base64,<base-64-encode-bytes>
- see here for more details. IMPORTANT - if you're not using PNG files, you'll need to change image/png
in that string appropriately.
Now to get the bytes into the format - converting the Image
instance into a string using ToString()
is not sufficient, however with a few extra steps it's possible. Use MemoryStream
and Convert
like so - this will give you the long string of bytes you can embed in your response. Again, if you don't want to use PNG, you'll need to change your Save
call appropriately.
string base64 = "";
using (MemoryStream stream = new MemoryStream())
{
u.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
base64 = Convert.ToBase64String(stream.ToArray());
}
Important side note - if these images are very big, then embedding might not be a good idea for performance reasons. But for small images this should be OK.
Upvotes: 0
Reputation: 288
When you add u (Image variable) to a string, .NET framework will call u.ToString() and add the output to the string, so the result string will be <img src="Image"</img>
If you need to make it correct:
Either pass the URL of the image, if its on a common place.
Base64 encode the image and keep it inline (within the html). Example:
<img alt="Embedded Image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA..." />
Upvotes: 2