views:

6280

answers:

6

I'm trying to write a simple routine where I pass it a URL and it goes and renders the content of the webresponse as a jpg. I found a solution somehwere in C# and ported it to vb.net, however when I run it, it throws an argumentexception "parameter is not valid" when trying to instantiate the image. Can someone take a look at the following code and let me know if I'm on the right track?

Sub SaveUrl(ByVal aUrl As String)
    Dim response As WebResponse
    Dim remoteStream As Stream
    Dim readStream As StreamReader
    Dim request As WebRequest = WebRequest.Create(aUrl)
    response = request.GetResponse
    remoteStream = response.GetResponseStream
    readStream = New StreamReader(remoteStream)
    Dim img As System.Drawing.Image = System.Drawing.Image.FromStream(remoteStream)
    img.Save(aUrl & ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
    response.Close()
    remoteStream.Close()
    readStream.Close()
End Sub

To Clarify: Yes, I know i need a LOT more code to accomplish what I want to do, which is to render/take a screen capture of a URL (html, images, all the markup, everything) and save it as a jpg thumbnail.

If you've used Google Chrome, you've seen the launch page that has thumbnails of all the sites you use frequently. Something like that.

Update: Ok I've found commercial paid products to accomplish this, like http://www.websitesscreenshot.com/Index.html but no open source implementations.

+2  A: 

What are you trying to do?

Are you trying convert a web page to JPEG? This will require a bit more code, as what your code is trying to do is to download an already existing image (such as a gif, png, or even another jpeg) and converts it to jpeg. You would need to have something render the HTML document, then you would need to capture an image of the rendered document, and then save that as a JPEG.

Yuliy
Thats correct. Any clues as to what I can use to render the document and save it as a jpg?
DaveJustDave
You might be able to use a Winforms WebBrowser (http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser_members.aspx). I don't know what you would use to then take a screenshot from this.
Yuliy
+3  A: 

Just because the Image class has a .FromStream() method doesn't mean that any stream is a valid image, and the html response from a web server certainly would not be a valid image. Rendering a web page is not a "simple routine". There's a lot that goes into it.

You might try using the WebBrowser control, since that can do a lot of the work for you.

Joel Coehoorn
+2  A: 

It's probably easier to use System.Net.WebClient, I think you can remove all but 2 or 3 lines of code. i.e.: WebClient.DownloadFile()

MSDN page

Zachary Yates
That will just get the html text: it still won't get the image, nor any other images, styles, or scripts the page may need to render.
Joel Coehoorn
+1  A: 

I know you're asking for VB, but here's some C# code that I use in a project of mine to capture local thumbnails from image URLs (asynchronously). I've tried to strip out all the project-specific stuff so it makes sense as a stand-alone example.

var wc = new WebClient();
wc.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
wc.DownloadDataCompleted += wc_DownloadDataCompleted;

wc.DownloadDataAsync(imageProvider.Image, "yourFilenameHere");

And here's the wc_DownloadDataCompleted event handler:

private void wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
    if (e.Error == null && !e.Cancelled)
    {
        var filename = e.UserState.ToString();

        using (var ms = new MemoryStream(e.Result))
        {
            var bi = new BitmapImage();
            bi.BeginInit();
            bi.StreamSource = ms;
            bi.DecodePixelWidth = 80; // _maxThumbnailWidth;
            bi.EndInit();

            var encoder = new JpegBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(bi));
            var filename = Path.Combine(_thumbFolder, filename);
            try
            {
                using (var fs = new FileStream(filename, FileMode.Create))
                {
                    encoder.Save(fs);
                }
            }
            catch { }
        }
    }
}

Edit

I guess I should add that this was in a WPF application - hence the use of "BitmapImage" and "BitmapFrame" to decode the stream. So it may not help you. I'm gonna leave it here anyway.

Matt Hamilton
+1  A: 

Well, either:

My.Computer.Network.DownloadFile("http://example.com/file.jpeg", "local.jpeg")

Or, to create a thumbnail:

Using wc As New Net.WebClient()
    Dim img = Image.FromStream(wc.OpenRead("http://example.com/file"))
    img.GetThumbnailImage(32, 32, Function() False, Nothing).Save("c:\local.jpg")
End Using

… maybe add some error handling. ;-)

Konrad Rudolph
I get the impression that he's downloading an html page rather than an image file, and want a thumbnail of the html page.
Joel Coehoorn
@Joel, yes I've now read the clarification as well. I posted my code before that, since it's basically was his code is doing as well, only much shorter. I'll let it stand because I think it could still be useful for other people.
Konrad Rudolph
+2  A: 

Hi, I've just found a German code snippet on ActiveVB that creates a screenshot form a web site. Perhaps you can build on that? Unfortunately, the code is not only explained in German, but also in VB6. Still, the logic is essentially the same and shouldn't be hard to port to .NET. Hope that helps.

Konrad Rudolph