Monday, 2 April 2012

C# Convert html page to image

* Add references to System.Windows.Forms and System.Drawing

public class HtmlRenderer
{
  public static void Render(string inputUrl, string outputPath, Rectangle crop)
  {    
    WebBrowser wb = new WebBrowser();
    wb.ScrollBarsEnabled = false;
    wb.ScriptErrorsSuppressed = true;
    wb.Navigate(inputUrl);
    while (wb.ReadyState != WebBrowserReadyState.Complete)
    {
      Application.DoEvents();
    }
    wb.Width = wb.Document.Body.ScrollRectangle.Width;
    wb.Height = wb.Document.Body.ScrollRectangle.Height;
    using (Bitmap bitmap = new Bitmap(wb.Width, wb.Height))
    {
      wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));
      wb.Dispose();
      Rectangle rect = new Rectangle(crop.Left, crop.Top, wb.Width - crop.Width - crop.Left, wb.Height - crop.Height - crop.Top);
      Bitmap cropped = bitmap.Clone(rect, bitmap.PixelFormat);
      cropped.Save(outputPath, ImageFormat.Png);
    }
  }
}

You need to run it from the thread in Single Threaded Apartment

[STAThread]
static void Main(string[] args)
{
    HtmlRenderer.Render(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Test.htm"), "Test.png",new Rectangle(0, 0, 0, 0));
}

or

static void Main(string[] args)
{
    var t = new Thread(() => HtmlRenderer.Render(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Test.htm"), "Test.png", new Rectangle(0, 0, 0, 0)));
    t.SetApartmentState(ApartmentState.STA);
    t.Start();
}