public static class NativeMethods
{
private const int SM_CXVSCROLL = 2;
[ComImport]
[Guid("0000010D-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IViewObject
{
void Draw([MarshalAs(UnmanagedType.U4)] uint dwAspect, int lindex, IntPtr pvAspect, [In] IntPtr ptd, IntPtr hdcTargetDev, IntPtr hdcDraw, [MarshalAs(UnmanagedType.Struct)] ref Rect lprcBounds, [In] IntPtr lprcWBounds, IntPtr pfnContinue, [MarshalAs(UnmanagedType.U4)] uint dwContinue);
}
public static int GetSystemMetrics()
{
return GetSystemMetrics(SM_CXVSCROLL);
}
[DllImport("user32.dll")]
public static extern int GetSystemMetrics(int smIndex);
public static void GetImage(object obj, Image destination, Color backgroundColor)
{
using (var graphics = Graphics.FromImage(destination))
{
var deviceContextHandle = IntPtr.Zero;
var rectangle =
new Rect
{
Right = destination.Width,
Bottom = destination.Height
};
graphics.Clear(backgroundColor);
try
{
deviceContextHandle = graphics.GetHdc();
var viewObject = obj as IViewObject;
viewObject.Draw(1, -1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, deviceContextHandle, ref rectangle, IntPtr.Zero, IntPtr.Zero, 0);
}
finally
{
if (deviceContextHandle != IntPtr.Zero)
{
graphics.ReleaseHdc(deviceContextHandle);
}
}
}
}
}
Heres where the magic happens
public class HtmlToBitmapConverter : IDisposable
{
private const int SleepTimeMiliseconds = 5000;
internal static Bitmap Output;
public Bitmap Render(string html, Size size)
{
var browser = CreateBrowser(size);
browser.Navigate("about:blank");
browser.Document.Write(html);
Output = GetBitmapFromControl(browser, size);
return Output;
}
public Bitmap Render(Uri uri, Size size)
{
var browser = CreateBrowser(size);
NavigateAndWaitForLoad(browser, uri, 0);
Output = GetBitmapFromControl(browser, size);
return Output;
}
public void NavigateAndWaitForLoad(WebBrowser browser, Uri uri, int waitTime)
{
browser.Navigate(uri);
var count = 0;
while (browser.ReadyState != WebBrowserReadyState.Complete)
{
Thread.Sleep(SleepTimeMiliseconds);
Application.DoEvents();
count++;
if (count > waitTime / SleepTimeMiliseconds)
{
break;
}
}
while (browser.Document.Body == null)
{
Application.DoEvents();
}
HideScrollBars(browser);
}
private void HideScrollBars(WebBrowser browser)
{
const string Hidden = "hidden";
var document = (IHTMLDocument2)browser.Document.DomDocument;
var style = (IHTMLStyle2)document.body.style;
style.overflowX = Hidden;
style.overflowY = Hidden;
}
private WebBrowser CreateBrowser(Size size)
{
var
newBrowser =
new WebBrowser
{
ScrollBarsEnabled = false,
ScriptErrorsSuppressed = true,
Size = size
};
newBrowser.BringToFront();
return newBrowser;
}
private Bitmap GetBitmapFromControl(WebBrowser browser, Size size)
{
var bitmap = new Bitmap(size.Width, size.Height);
NativeMethods.GetImage(browser.Document.DomDocument, bitmap, Color.White);
return bitmap;
}
void IDisposable.Dispose()
{
GC.SuppressFinalize(this);
}
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct Rect
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}