How to save Html to JPG/JPEG Image and how to save it in best quality?
On recent project, I had a tasks to:
- Save result of Html page to JPG image
- To do that in best possible quality
Both tasks sounds trivial, but I did not find quite satisfying solutions, so, I came up with one bellow.
First, you need WebBrowser control – it is basicaly wrapper around ActiveX Internet Explorer interface.
Once when Html content is ready (local or remote), ask control to call your procedure upon completion:
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
and start render your content:
webBrowser1.Navigate( UriToRender )
In DocumentCompletedEventHandler, call your routine for rendering content to image:
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { if( GetImageFromHtml(currentFile, webBrowser1) ) { toolStripStatusLabel1.Text = "Image saved."; } else { toolStripStatusLabel1.Text = "Sorry, there was problem with saving."; } }
And here is code for rendering Html to image:
/// <summary> /// Method for saving Html content into image /// </summary> /// <param name="imageName">File name of image</param> /// <param name="webBrowser">Target WebBrowser control to query for content</param> /// <returns>True if save was succesfull</returns> /// <seealso cref="System.Windows.Forms.WebBrowser" /> public bool GetImageFromHtml(string imageName, WebBrowser webBrowser) { if (webBrowser.Document == null) { return false; } Cursor current = Cursor; Cursor = Cursors.WaitCursor; // Give time to WebBrowser control to finish rendering of document Thread.Sleep(200); try { // save old width / height Size originalSize = new Size(webBrowser1.Width, webBrowser1.Height); // Change to full scroll size int scrollHeight = webBrowser.Document.Body.ScrollRectangle.Height; int scrollWidth = webBrowser.Document.Body.ScrollRectangle.Width; Bitmap image = new Bitmap(scrollWidth, scrollHeight); webBrowser.Size = new Size(scrollWidth, scrollHeight); // Draw to image webBrowser.DrawToBitmap(image, webBrowser.ClientRectangle); webBrowser.Size = originalSize; // Old one with bad quality: // image.Save(imageName, ImageFormat.Jpeg); // Save in full quality SaveJPG(image, imageName, 100); return true; } catch { return false; } finally { Cursor = current; } }
Usual Image.Save method saves image in number of formats; however, quality is some default (bad) quality; and I needed more control over it. So, here are methods which allow that kind of control:
/// <summary> /// Gets codec info by given mimeType /// </summary> /// <param name="mimeType">mimeType to lookup for</param> /// <returns>ImageCodecInfo if all ok or null</returns> public static ImageCodecInfo GetCodecInfo(String mimeType) { ImageCodecInfo[] encoders; encoders = ImageCodecInfo.GetImageEncoders(); for (int iterator = 0; iterator < encoders.Length; ++iterator) { if (encoders[iterator].MimeType == mimeType) return encoders[iterator]; } return null; } /// <summary> /// Save an Image to JPEG with given compression quality /// </summary> /// <param name="image">Image to save</param> /// <param name="imageName">File name to store image</param> /// <param name="quality">Quality parameter: 0 - lowest quality, smallest size, /// 100 - max quality and size</param> /// <returns>True if save was succesfull</returns> public static bool SaveJPG(Image image, string imageName, long qual) { EncoderParameters eps = new EncoderParameters(1); eps.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qual); ImageCodecInfo ici = GetCodecInfo("image/jpeg"); if(ici == null) { return false; } image.Save(imageName, ici, eps); return true; }
Now you can select jpeg image quality and render html the way you like.