views:

9015

answers:

11

Hi. Does anyone know in .Net 2.0 - .Net 3.5 how to load a jpeg into a System.Windows.Forms.WebControl as a byte-array and with the right mimetypes set so it will show?

Something like:

webBrowser1.DocumentStream = new MemoryStream(File.ReadAllBytes("mypic.jpg"));
webBrowser1.DocumentType = "application/jpeg";

The webBrowser1.DocumentType seems to be read only, so I do not know how to do this. In general I want to be able to load any kind of filesource with a mimetype defined into the browser to show it.

Solutions with writing temp files are not good ones. Currently I have solved it with having a little local webserver socket listener that delivers the jpeg I ask for with the right mimetype.

A: 

You cannot do it. You cannot stuff images into Microsoft's web-browser control.

The limitation comes from the IWebBrowser control itself, which .NET wraps up.

Ian Boyd
A: 

Noooo. There MUST be a way to get this to work. :(
There isn't any hacky way of doing this? I seldom give up on such dilemmas and tend to find a workaround, but I have tried digging a few times on this one over a long period. But nada.

I do not want to load off from disk, and I do not want to serve a host for the browser to get its data from.

The reason I am using the browser is to show pictures or other files that have a IE plugin viewer, like Word or PDF or other viewers like that.

Is there any way to maybe use the plugins directly, bypassing the need for the IE host (webcontrol)? If so, that would be a solution.

Wolf5
A: 

If you want a total hack, try having your stream be the HTML file that only shows your picture. You lose your image byte stream and will have to write the image to disk.

Austin Salonen
A: 

But then we are back to writing to disk. I want it all to be done in-memory. If there a sensitive data to be shown, I do not want it to be written to disk in any way. Neither sniffable as network traffic.

Wolf5
A: 

I do not know whether the WebBrowser .NET control supports this, but RFC2397 defines how to use inline images. Using this and a XHTML snippet created on-the-fly, you could possibly assign the image without the need to write it to a file.

Image someImage = Image.FromFile("mypic.jpg");

// Firstly, get the image as a base64 encoded string
ImageConverter imageConverter = new ImageConverter();
byte[] buffer = (byte[])imageConverter.ConvertTo(someImage, typeof(byte[]));
string base64 = Convert.ToBase64String(buffer, Base64FormattingOptions.InsertLineBreaks);

// Then, dynamically create some XHTML for this (as this is just a sample, minimalistic XHTML :D)
string html = "<img src=\"data:image/" . someImage.RawFormat.ToString() . ";base64, " . $base64 . "\">";

// And put it into some stream
using (StreamWriter streamWriter = new StreamWriter(new MemoryStream()))
{
    streamWriter.Write(html);
    streamWriter.Flush();
    webBrowser.DocumentStream = streamWriter.BaseStream;
    webBrowser.DocumentType = "text/html";
}

No idea whether this solution is elegant, but I guess it is not. My excuse for not being sure is that it is late at night. :)

References:

hangy
I believe IE used to have no support for data:image stuff.
liggett78
I ran a small test yesterday (http://browsershots.org/http://aktuell.de.selfhtml.org/artikel/grafik/inline-images/) which shows that no IE but IE8 does. :( However, I have no clue what kind of rendering engine that WebBrowser control uses. :)
hangy
A: 

To bad you can not set: webBrowser.DocumentType = "text/html";

as it is read only. I'll check out the inline thing though.

Hmm but an idea emerges.

Since it can not be set, how about opening up X instances of the control, one for each mimetype/plugin that I want to show (opening a dummy file from disk). That way the mimetype will be changed, and maybe when loading the target file into .DocumentStream, it'll show correctly?

Will test out as soon as I can.

Wolf5
+2  A: 

You have to implement an async pluggable protocol, e.g. IClassFactory, IInternetProtocol... Then you use CoInternetGetSession to register your protocol. When IE calls your implementation, you can serve your image data from memory/provide mime type.

It's a bit tedious, but doable. Look at IInternetProtocol and pluggable protocols documentation on MSDN.

liggett78
A: 

Ah. Thanks. Will definately check that one out. Will comment back on this thread when I've done something.

Wolf5
+1  A: 

I have done what liggett78 suggests, and would just like to add that allthough it takes some work, it works great once in place.

Eyvind
+3  A: 

Thanks. It was EXACTLY a way to solve the problem.

Sample solution in C# here that works perfectly:

http://www.codeproject.com/KB/aspnet/AspxProtocol.aspx

All is done inmemory. Since the "talking" component has to be GACed and registered to work, I'll just create it in a static way with eventhandlers so that I can use it from my running application. Make it generic so I can use it in many ways.

It is strange how many times I have seen others asking the same question I have, and all have been let down with no solution. Hope this thread gets up there so people find the solution!

Wolf5
A: 

IE only support 32KB for inline images in base64 encoding, so not a good solution.

Seeker