threading & bitmap method c#
I am trying to get a screenshot from Browser control in c#. When I am trying to initialize the browser control, I am getting an error:
ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment.
Now what I am trying is that I am creating a thread and I am doing all the initizalization there, but I am getting an error when I am trying to declare the Response.ContentType = "image/jpeg";
The error message is:
Response is not available in this context.
Here is my complete code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Threading;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;
public partial class _Default : System.Web.UI.Page
{
string currentPageUrl = "";
Bitmap bmp = new Bitmap(1024, 768);
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (Request.ServerVariables["HTTPS"].ToString() == "")
{
currentPageUrl = Request.ServerVariables["SERVER_PROTOCOL"].ToString().ToLower().Substring(0, 4).ToString() + "://" + Request.ServerVariables["SERVER_NAME"].ToString() + ":" + Request.ServerVariables["SERVER_PORT"].ToString() + Request.ServerVariables["SCRIPT_NAME"].ToString();
}
else
{
currentPageUrl = Request.ServerVariables["SERVER_PROTOCOL"].ToString().ToLower().Substring(0, 5).ToString() + "://" + Request.ServerVariables["SERVER_NAME"].ToString() + ":" + Request.ServerVariables["SERVER_PORT"].ToString() + Request.ServerVariables["SCRIPT_NAME"].ToString();
}
Thread thr = new Thread(new ThreadStart(OptimizeWebBrowserAndCreateImage));
thr.SetApartmentState(ApartmentState.STA);
thr.Start();
}
protected void OptimizeWebBrowserAndCreateImage()
{
System.Windows.Forms.WebBrowser browser = new System.Windows.Forms.WebBrowser();
browser.ScrollBarsEnabled = false;
browser.ScriptErrorsSuppressed = true;
browser.Navigate(currentPageUrl);
while (browser.ReadyState != WebBrowserReadyState.Complete)
System.Windows.Forms.Application.DoEvents();
System.Threading.Thread.Sleep(1500);
int width = browser.Document.Body.ScrollRectangle.Width;
int height = browser.Document.Body.ScrollRectangle.Height;
browser.Width = width;
browser.Height = height;
开发者_如何学JAVA System.Drawing.Bitmap bmp = new Bitmap(width, height);
browser.DrawToBitmap(bmp, new System.Drawing.Rectangle(0, 0, width, height));
Response.ContentType = "image/jpeg";
Response.AppendHeader("Content-Disposition", "attachment; filename=screenshot.jpg");
bmp.Save(Response.OutputStream, ImageFormat.Jpeg);
bmp.Dispose();
bmp.Dispose();
Response.End();
}
}
I am getting an error as I said on Response.ContentType = "image/jpeg";
I appreciate your help and I hope that someone can help me fix this issue. Thanks in advance, Laziale
Updated Version based on Henk's advice:using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Threading;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;
public partial class _Default : System.Web.UI.Page
{
string currentPageUrl = "";
Bitmap bmp = new Bitmap(1024, 768);
Thread thr = null;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (Request.ServerVariables["HTTPS"].ToString() == "")
{
currentPageUrl = Request.ServerVariables["SERVER_PROTOCOL"].ToString().ToLower().Substring(0, 4).ToString() + "://" + Request.ServerVariables["SERVER_NAME"].ToString() + ":" + Request.ServerVariables["SERVER_PORT"].ToString() + Request.ServerVariables["SCRIPT_NAME"].ToString();
}
else
{
currentPageUrl = Request.ServerVariables["SERVER_PROTOCOL"].ToString().ToLower().Substring(0, 5).ToString() + "://" + Request.ServerVariables["SERVER_NAME"].ToString() + ":" + Request.ServerVariables["SERVER_PORT"].ToString() + Request.ServerVariables["SCRIPT_NAME"].ToString();
}
thr = new Thread(new ThreadStart(OptimizeWebBrowserAndCreateImage));
thr.SetApartmentState(ApartmentState.STA);
thr.Start();
}
protected void OptimizeWebBrowserAndCreateImage()
{
/*
Bitmap bitmap = new Bitmap(CaptureWebPage2(currentPageUrl));
Response.ContentType = "image/jpeg";
Response.AppendHeader("Content-Disposition", "attachment; filename=screenshot.jpg");
bitmap.Save(Response.OutputStream, ImageFormat.Jpeg);
bitmap.Dispose();
bitmap.Dispose();
Response.End();
*/
System.Windows.Forms.WebBrowser browser = new System.Windows.Forms.WebBrowser();
browser.ScrollBarsEnabled = false;
browser.ScriptErrorsSuppressed = true;
browser.Navigate(currentPageUrl);
while (browser.ReadyState != WebBrowserReadyState.Complete)
System.Windows.Forms.Application.DoEvents();
System.Threading.Thread.Sleep(1500);
int width = browser.Document.Body.ScrollRectangle.Width;
int height = browser.Document.Body.ScrollRectangle.Height;
browser.Width = width;
browser.Height = height;
System.Drawing.Bitmap bmp = new Bitmap(width, height);
browser.DrawToBitmap(bmp, new System.Drawing.Rectangle(0, 0, width, height));
/* Response.ContentType = "image/jpeg";
Response.AppendHeader("Content-Disposition", "attachment; filename=screenshot.jpg");
bmp.Save(Response.OutputStream, ImageFormat.Jpeg);
bmp.Dispose();
bmp.Dispose();
Response.End();
*/
}
protected void Page_PreRender(object sender, EventArgs e)
{
if (thr != null)
{
thr.Join();
Response.ContentType = "image/jpeg";
Response.AppendHeader("Content-Disposition", "attachment; filename=screenshot.jpg");
bmp.Save(Response.OutputStream, ImageFormat.Jpeg);
bmp.Dispose();
//bmp.Dispose();
Response.End();
}
}
}
You are running a separate thread, so that is running outside of the HttpContext. That's why you get no useful Response (or Request or Session). So pass the Context as parameter to your method and get the Response from there.
Or rewrite your code so that the method doesn't depend on the HttpContext (as that may not be thread safe). Pick up the Bitmap result later in the page lifecycle where you do have a Response that you can use.
You are inside a browser, thus you can get the data of the web page using the Document property of the WebBrowser.
How to get the data from the document, depends then on the document itself.
I can also not see where you are initalising the Response. Is this missing in the posted code?
精彩评论