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.
