I searched for free open source csharp to convert html to image. I found solution using:
WebBrowser (namespace System.Windows.Forms) code below is sample of conversion:
static byte[] CaptureWebPageBytesP(string body, int? width, int? height) { byte[] data; // create a hidden web browser, which will navigate to the page using (WebBrowser web = new WebBrowser()) { web.ScrollBarsEnabled = false; // we don't want scrollbars on our image web.ScriptErrorsSuppressed = true; // don't let any errors shine through web.Navigate("about:blank"); // wait until the page is fully loaded while (web.ReadyState != System.Windows.Forms.WebBrowserReadyState.Complete) System.Windows.Forms.Application.DoEvents(); web.Document.Body.InnerHtml = body;
// set the size of our web browser to be the same size as the page if (width == null) width = web.Document.Body.ScrollRectangle.Width; if (height == null) height = web.Document.Body.ScrollRectangle.Height; web.Width = width.Value; web.Height = height.Value; // a bitmap that we will draw to using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width.Value, height.Value)) { // draw the web browser to the bitmap web.DrawToBitmap(bmp, new Rectangle(web.Location.X, web.Location.Y, web.Width, web.Height)); // draw the web browser to the bitmap using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) { EncoderParameter qualityParam = null; EncoderParameters encoderParams = null; try { ImageCodecInfo imageCodec = null; //imageCodec = getEncoderInfo("image/jpeg"); imageCodec = getEncoderInfo("image/bmp");
// Encoder parameter for image quality qualityParam = new EncoderParameter(Encoder.Quality, 100L);
encoderParams = new EncoderParameters(1); encoderParams.Param[0] = qualityParam; bmp.Save(stream, imageCodec, encoderParams); } catch (Exception) { throw new Exception(); } finally { if (encoderParams != null) encoderParams.Dispose(); if (qualityParam != null) qualityParam.Dispose(); } bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); stream.Position = 0; data = new byte[stream.Length]; stream.Read(data, 0, (int)stream.Length); } } } return data; }
|
But I faced problem when I try to use it without Window Forms (console application, aspnet, or windows service) It gave me error cannot be instantiated because the current thread is not in a single-threaded. To solve this error created STAThread like code below:
public static byte[] CaptureWebPageBytes(string body, int? width, int? height) { bool bDone = false; byte[] data = null; DateTime startDate = DateTime.Now; DateTime endDate = DateTime.Now;
//sta thread to allow intiate WebBrowser var staThread = new Thread(delegate() { data = CaptureWebPageBytesP(body, width, height); bDone = true; }); staThread.SetApartmentState(ApartmentState.STA); staThread.Start(); while (!bDone) { endDate = DateTime.Now; TimeSpan tsp = endDate.Subtract(startDate);
Application.DoEvents(); if (tsp.Seconds > 50) { break; } } staThread.Abort(); return data; } |