Server for displaying pictures in web browser - c#

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.

Related

Can we store HTML in attachment?

I am trying to save HTML in attachment, using mail kit I am downloading the attachment and store it in a database in byte[] for that I need to convert attachment in the stream but while converting HTML document in the stream it shows me zero length in stream for all other document code is working fine.
Below is the code which I am using:
using (var stream = File.Create(fileName))
{
if (attachment is MessagePart)
{
var rfc822 = (MessagePart)attachment;
rfc822.Message.WriteTo(stream);
}
else
{
var part = (MimePart)attachment;
part.ContentObject.DecodeTo(stream);
}
int length = Convert.ToInt32(stream.Length);
attachments.strFileName = fileName;
attachments.strAttachment = new byte[length];
stream.Read(attachments.strAttachment, 0, length);
stream.Close();
}
You need to rewind the stream before you'll be able to read the content.
stream.Position = 0;

How to stream a motion jpeg using owin/katana?

I am self hosting OWIN/KATANA in a windows service. Right now I have implemented a way to grab a single image from a camera. I would like to grab multiple frames from the camera and stream them back to a img tag on an html page. Is this possible with OWIN/KATANA?
app.Map("/Camera/Video", a =>
{
a.Run(context =>
{
string connectionid = CurrentDevice.Value.ToString();
object ret = DeviceManager.Instance.SendMessageToDevice(connectionid, "startmovie");
context.Response.Headers.Add("Content-Type", new string[] { "multipart/x-mixed-replace; boundary=--jpgboundary" });
bool con = true;
StreamWriter writer = new StreamWriter(context.Response.Body);
while (con)
{
using (MemoryStream ms = new MemoryStream())
{
Image img = (Image)DeviceManager.Instance.SendMessageToDevice(connectionid, "capturestill");
img.Save(ms, ImageFormat.Jpeg);
byte[] buffer = ms.GetBuffer();
writer.WriteLine("--jpgboundary");
writer.WriteLine("Content-Type: image/jpeg");
writer.WriteLine(string.Format("Content-length: {0}", buffer.Length));
writer.WriteLine();
context.Response.Write(buffer);
//writer.WriteLine(Convert.ToBase64String(buffer));
writer.Flush();
}
Thread.Sleep(200);
}
DeviceManager.Instance.SendMessageToDevice(connectionid, "stopmovie");
return context.Response.WriteAsync("");
});
});
I figured out what my issue was. I was using WriteAsync and I needed to use just the Write. The above works great. I just need to figure out how to stop it now.

how to make bar-code label from encrypted text

i am using USPS service. when i sent request for tracking label i got out put of encrypted text now i should make that encrypted text to bar code label.
I have tried following code but did not get any result. i C# (ASP.net) i am using
System.Drawing.Image newImage;
string str = "JVBERi0xLjINCjUgMCBvYmoNCjw8DQovVHlwZSAvWE9iamVjdA0KL1N1YnR5cGUg....";
byte[] arr = System.Text.Encoding.ASCII.GetBytes(str);
string strFileName = GetTempFolderName() + "yourfilename.gif";
if (byteArrayIn != null)
{
using (MemoryStream stream = new MemoryStream(byteArrayIn))
{
newImage = System.Drawing.Image.FromStream(stream);
newImage.Save(strFileName);
Image11.Attributes.Add("src", strFileName);
}
}
}
Please help me if you have any solution
Regards
sanjay

Using Dumpyourphoto photo hosting via C#

I am currently trying to make a simple photo upload function that will upload a screenshot that I took. I found this website dumpyourphoto.com but I don't really understand how to do it in C#. Can anyone guide me through this?
Basically all I need is to upload a screenshot photo up to the server and hopefully it will return me a url to that photo. From there on, I will upload this URL up to a OpenShift database that I already set up and upload it as a text and store the link in the database.
Right. Thanks Simon for the question. I realised I didn't put much details up.
So basically I took a screenshot using kinect and this is the function that I am using.
private void btn_ss_Click(object sender, RoutedEventArgs e)
{
// create a png bitmap encoder which knows how to save a .png file
BitmapEncoder encoder = new PngBitmapEncoder();
// create frame from the writable bitmap and add to encoder
encoder.Frames.Add(BitmapFrame.Create(this.colorBitmap));
string time = System.DateTime.Now.ToString("hh'-'mm'-'ss", CultureInfo.CurrentUICulture.DateTimeFormat);
string myPhotos = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string path = System.IO.Path.Combine(myPhotos, "KinectSnapshot-" + time + ".png");
// write the new file to disk
try
{
using (FileStream fs = new FileStream(path, FileMode.Create))
{
encoder.Save(fs);
}
this.ss_dis.Text = string.Format("{0} {1}", "Screenshot has been taken.", path);
}
catch (IOException)
{
this.ss_dis.Text = string.Format("{0} {1}", "Failed to take Screenshot.", path);
}
}
The part that I am struggling is that I have never really dealt with web activities such as HttpWebRequest functions before and the website shows xml and json. I have a slight idea of how to do it but I am not too sure.
This is the link to the developer api.
http://www.dumpyourphoto.com/information/api
Update: I tried to work things out myself but I am stuck at this last part. I don't know how to attach the bytearray and key to the HttpWebRequest.
private byte[] imgToByteArray(string _FileName)
{
byte[] _buffer = null;
try
{
System.IO.FileStream _FileStream = new System.IO.FileStream(_FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
System.IO.BinaryReader _BinaryReader = new System.IO.BinaryReader(_FileStream);
long _TotalByte = new System.IO.FileInfo(_FileName).Length;
_buffer = _BinaryReader.ReadBytes((Int32)_TotalByte);
_FileStream.Close();
_FileStream.Dispose();
_BinaryReader.Close();
}
catch(Exception _Exception)
{
Console.WriteLine("Exception caught in process: {0}", _Exception.ToString());
}
return _buffer;
}
This is the Image to ByteArray function.
private void button1_Click(object sender, RoutedEventArgs e)
{
string imgPath = "C:\\KinectSnapshot-04-46-14.png";
string key = "1d533e9033f9d5b9b509055d8a00932aaf1ace7f";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.dumpyourphoto.com/api/upload_photo/xml");
string path = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "KinectSnapshot-" + "03-38-28" + ".png");
byte[] img = imgToByteArray(path);
request.Method = "POST";
request.Credentials = CredentialCache.DefaultCredentials;
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = img.Length;
using(Stream dataStream = request.GetRequestStream())
dataStream.Write(img, 0, img.Length);
using (WebResponse response = request.GetResponse())
using(Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
{
string responseResults = reader.ReadToEnd();
Console.WriteLine(responseResults);
}
}
Update: This is where I am currently. I have 2 problems left. I don't know where to attach the key file and the title of the uploaded picture. Can anyone enlighten me on this?
I would really appreciate any help I can get!
You would use HttpWebRequest to make a POST request using the methods listed in their API. Is there something specific you're struggling with?

c# HttpWebRequest POST'ing failing

So i'm trying to POST something to a webserver.
System.Net.HttpWebRequest EventReq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create("url");
System.String Content = "id=" + Id;
EventReq.ContentLength = System.Text.Encoding.UTF8.GetByteCount(Content);
EventReq.Method = "POST";
EventReq.ContentType = "application/x-www-form-urlencoded";
System.IO.StreamWriter sw = new System.IO.StreamWriter(EventReq.GetRequestStream(), System.Text.Encoding.UTF8);
sw.Write(Content);
sw.Flush();
sw.Close();
Looks alright, i'm setting content-length based on the size of the ENCODED data...
Anyway it fails at sw.flush() with "bytes to be written to the stream exceed the Content-Length size specified"
Is StreamWriter doing some magic behind my back i'm not aware of? Is there a way i can peer into what StreamWriter is doing?
Other answers have explained how to avoid this, but I thought I'd answer why it's happening: you're ending up with a byte order mark before your actual content.
You can avoid this by calling new UTF8Encoding(false) instead of using Encoding.UTF8. Here's a short program to demonstrate the difference:
using System;
using System.Text;
using System.IO;
class Test
{
static void Main()
{
Encoding enc = new UTF8Encoding(false); // Prints 1 1
// Encoding enc = Encoding.UTF8; // Prints 1 4
string content = "x";
Console.WriteLine(enc.GetByteCount("x"));
MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms, enc);
sw.Write(content);
sw.Flush();
Console.WriteLine(ms.Length);
}
}
Maybe make like easier:
using(WebClient client = new WebClient()) {
NameValueCollection values = new NameValueCollection();
values.Add("id",Id);
byte[] resp = client.UploadValues("url","POST", values);
}
Or see here for a discussion allowing use like:
client.Post(destUri, new {
id = Id // other values here
});
You need not set ContentLength explicitly, since it will be set automatically to the size of data written to request stream when you close it.

Categories