threading & bitmap method c#

£可爱£侵袭症+ 提交于 2019-12-11 13:36:16

问题


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

回答1:


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.




回答2:


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?



来源:https://stackoverflow.com/questions/6895856/threading-bitmap-method-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!