Showing posts with label Conversion. Show all posts
Showing posts with label Conversion. Show all posts

Saturday, January 22, 2011

Convert Html to Image

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;
}