How to Read a Local MJPEG File - c#

I'm writing an App for Windows Phone in XNA... and I'd like to read a MJPEG stream stored in the App's resources. I've found many examples of how to get a MJPEG from a website via WebHttpRequest like this:
// get the response
HttpWebRequest request = (HttpWebRequest) asyncResult.AsyncState;
HttpWebResponse response = (HttpWebResponse) request.EndGetResponse(asyncResult);
try {
// find boundary value
string contentType = response.Headers["Content-Type"];
if (!String.IsNullOrEmpty(contentType) && !contentType.Contains("=")) {
throw new FormatException("Invalid content-type header. The source is likely not returning a proper MJPEG stream.");
}
string boundary = response.Headers["Content-Type"].Split('=')[1].Replace("\"", "");
byte[] boundaryBytes = Encoding.UTF8.GetBytes(boundary.StartsWith("--") ? boundary : "--" + boundary);
using (Stream stream = response.GetResponseStream()) {
using (BinaryReader binaryReader = new BinaryReader(stream)) {
// code to parse the MJPEG stream
}
}
} finally {
response.Close();
}
... but this is not exactly what I'm looking for. Here below is my code for reading the MJPEG as a binary stream from the App's resources:
private void ParseMjpeg(object uri)
{
// what the corresponding code for determining the boundary bytes in my local MJPEG?
byte[] boundaryBytes = ???
using (Stream stream = TitleContainer.OpenStream(uri.ToString())) {
using (BinaryReader binaryReader = new BinaryReader(stream)) {
// code to parse the MJPEG stream as before: OK
}
}
}
How do I determine the boundary bytes in my code here above? Any help would be REALLY appreciated.
Thanks,
j3d

this should make your life a lot easier. As far as I understand the DLL should provide you with most of what you need.
http://channel9.msdn.com/coding4fun/articles/MJPEG-Decoder

Related

How to add an image from URL to Excel Worksheet via C#

Here is the goal:
1) Get image from URL, in this case Google Static Maps API
2) Insert this image into an Excel Worksheet. I am okay if I have to create (or use an existing) shape and set the background to the image. I am also okay inserting at specific cells. I can define the image size via the Google Static Maps API (see URL above) so it will always be known.
I am not entirely clear on how to do this WITHOUT saving the file directly to the file system first.
I currently have code like this which gets the image in a MemoryStream format:
public static MemoryStream GetStaticMapMemoryStream(string requestUrl, string strFileLocation)
{
try
{
HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception(String.Format(
"Server error (HTTP {0}: {1}).",
response.StatusCode,
response.StatusDescription));
using (BinaryReader reader = new BinaryReader(response.GetResponseStream()))
{
Byte[] lnByte = reader.ReadBytes(1 * 700 * 500 * 10);
using (FileStream lxFS = new FileStream(strFileLocation, FileMode.Create))
{
lxFS.Write(lnByte, 0, lnByte.Length);
}
MemoryStream msNew = new MemoryStream();
msNew.Write(lnByte, 0, lnByte.Length);
return msNew;
}
}
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
return null;
}
}
Note that in the middle of the above code, I write the image to the file system as well. I'd like to avoid this part if at all possible.
At any rate, my code can create a rectangle, call the above sequence which saves the image, and then grab the image and populate the background of the rectangle:
Excel.Shape shapeStaticMap = wsNew2.Shapes.AddShape(Office.MsoAutoShapeType.msoShapeRectangle, 0, 0, 700, 500);
string strFileLocation = #"C:\Temp\test.jpg";
MemoryStream newMS = GetStaticMapMemoryStream(strStaticMapUrl, strFileLocation);
shapeStaticMap.Fill.UserPicture(strFileLocation);
So the real problem here is that I'd like to skip the "write to file and then grab from file" back-and-forth. It seems like an unnecessary step, and I anticipate that it will also get messy with file permissions and what-not.
UPDATE
Okay, so I basically gave up and left it using a local file. That worked for a while, but now I'm trying to re-work this code to grab an image from a different source where I don't know the image size in advance. The method above requires me to know the SIZE of the image in advance. How do I modify the code above to use any image size dynamically?
Use this version of GetStaticMapMemoryStream:
public static MemoryStream GetStaticMapMemoryStream(string requestUrl)
{
try
{
HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception(String.Format(
"Server error (HTTP {0}: {1}).",
response.StatusCode,
response.StatusDescription));
var responseStream = response.GetResponseStream();
var memoryStream = new MemoryStream();
responseStream.CopyTo(memoryStream);
memoryStream.Position = 0;
return memoryStream;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return null;
}
}

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?

using http response how to save the pdf files

I've written following code to get the content from a web page and save to the system.
if the webpage is in html format i'm able to save it.
if the web page is in pdf format i'm unable to save it. After saving if i opend the file blank pages are coming.
I want to know How to save the pdf files from the response.
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(Url);
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
webContent = reader.ReadToEnd();
StreamWriter sw = new StreamWriter(FileName);
sw.WriteLine(webContent);
sw.Close();
Please help me ASAP.
StreamReader.ReadToEnd() returns a string. PDF files are binary, and contain data that is not string-friendly. You need to read it into a byte array, and write the byte array to disk. Even better, use a smaller byte array as a buffer and read in small chunks.
You can also simplify the whole thing by just using webclient:
using (var wc = new System.Net.WebClient())
{
wc.DownloadFile(Url, FileName);
}
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(Url);
WebResponse response = request.GetResponse();
using (Stream stream = response.GetResponseStream())
using (FileStream fs = new FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.None))
{
stream.BlockCopy(fs);
}
...
public static class StreamHelper
{
public static void Copy(Stream source, Stream target, int blockSize)
{
int read;
byte[] buffer = new byte[blockSize];
while ((read = source.Read(buffer, 0, blockSize)) > 0)
{
target.Write(buffer, 0, read);
}
}
public static void BlockCopy(this Stream source, Stream target, int blockSize = 65536)
{
Copy(source, target, blockSize);
}
}

Convert to Stream from a Url

I was trying to convert an Url to Stream but I am not sure whether I am right or wrong.
protected Stream GetStream(String gazouUrl)
{
Stream rtn = null;
HttpWebRequest aRequest = (HttpWebRequest)WebRequest.Create(gazouUrl);
HttpWebResponse aResponse = (HttpWebResponse)aRequest.GetResponse();
using (StreamReader sReader = new StreamReader(aResponse.GetResponseStream(), System.Text.Encoding.Default))
{
rtn = sReader.BaseStream;
}
return rtn;
}
Am I on the right track?
I ended up doing a smaller version and using WebClient instead the old Http Request code:
private static Stream GetStreamFromUrl(string url)
{
byte[] imageData = null;
using (var wc = new System.Net.WebClient())
imageData = wc.DownloadData(url);
return new MemoryStream(imageData);
}
You don't need to create a StreamReader there. Just return aResponse.GetResponseStream();. The caller of that method will also need to call Dispose on the stream when it's done.
The current answer is missing an example in how to use GetResponseStream()
Here is an example
// Creates an HttpWebRequest with the specified URL.
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
// Sends the HttpWebRequest and waits for the response.
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
// Gets the stream associated with the response.
Stream receiveStream = myHttpWebResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader( receiveStream, encode );
Console.WriteLine("\r\nResponse stream received.");
Char[] read = new Char[256];
// Reads 256 characters at a time.
int count = readStream.Read( read, 0, 256 );
Console.WriteLine("HTML...\r\n");
while (count > 0)
{
// Dumps the 256 characters on a string and displays the string to the console.
String str = new String(read, 0, count);
Console.Write(str);
count = readStream.Read(read, 0, 256);
}
Console.WriteLine("");
// Releases the resources of the response.
myHttpWebResponse.Close();
// Releases the resources of the Stream.
readStream.Close();
For more details see - https://learn.microsoft.com/en-us/dotnet/api/system.net.httpwebresponse.getresponsestream?view=net-5.0

How to use WebResponse to Download .wmv file

I'm using the following code to grab a wmv file through a WebResponse. I'm using a thread to call this function:
static void GetPage(object data)
{
// Cast the object to a ThreadInfo
ThreadInfo ti = (ThreadInfo)data;
// Request the URL
WebResponse wr = WebRequest.Create(ti.url).GetResponse();
// Display the value for the Content-Length header
Console.WriteLine(ti.url + ": " + wr.Headers["Content-Length"]);
string toBeSaved = #"C:\Users\Kevin\Downloads\TempFiles" + wr.ResponseUri.PathAndQuery;
StreamWriter streamWriter = new StreamWriter(toBeSaved);
MemoryStream m = new MemoryStream();
Stream receiveStream = wr.GetResponseStream();
using (StreamReader sr = new StreamReader(receiveStream))
{
while (sr.Peek() >= 0)
{
m.WriteByte((byte)sr.Read());
}
streamWriter.Write(sr.ReadToEnd());
sr.Close();
wr.Close();
}
streamWriter.Flush();
streamWriter.Close();
// streamReader.Close();
// Let the parent thread know the process is done
ti.are.Set();
wr.Close();
}
The file seems to download just fine, but Windows Media Viewer cannot open the file properly. Some silly error about not being able to support the file type.
What incredibly easy thing am I missing?
You just need to download it as binary instead of text. Here's a method that should do the trick for you.
public void DownloadFile(string url, string toLocalPath)
{
byte[] result = null;
byte[] buffer = new byte[4097];
WebRequest wr = WebRequest.Create(url);
WebResponse response = wr.GetResponse();
Stream responseStream = response.GetResponseStream;
MemoryStream memoryStream = new MemoryStream();
int count = 0;
do {
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, count);
if (count == 0) {
break;
}
}
while (true);
result = memoryStream.ToArray;
FileStream fs = new FileStream(toLocalPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
fs.Write(result, 0, result.Length);
fs.Close();
memoryStream.Close();
responseStream.Close();
}
I do not understand why you are filling MemoryStream m one byte at a time, but then writing the sr to the file. At that point, I believe the sr is empty, and MemoryStream m is never used.
Below is some code I wrote to do a similar task. It gets a WebResponse in 32K chunks at a time, and dumps it directly to a file.
public void GetStream()
{
// ASSUME: String URL is set to a valid URL.
// ASSUME: String Storage is set to valid filename.
Stream response = WebRequest.Create(URL).GetResponse().GetResponseStream();
using (FileStream fs = File.Create(Storage))
{
Byte[] buffer = new Byte[32*1024];
int read = response.Read(buffer,0,buffer.Length);
while (read > 0)
{
fs.Write(buffer,0,read);
read = response.Read(buffer,0,buffer.Length);
}
}
// NOTE: Various Flush and Close of streams and storage not shown here.
}
You are using a StreamReader and a StreamWriter to transfer your stream, but those classes are for handling text. Your file is binary and chances are that sequences of CR, LF and CR LF may get clobbered when you transfer the data. How NUL characters are handled I have no idea.

Categories