2

我正在努力寻找一种在 MVC4 中截取网站截图的方法。我见过两种可能的解决方案,它们都不适用于 MVC。

第一个是使用 WebBrowser,教程在这里找到,但这给了我一个ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment错误。

另一个是使用名为Grabz.It的 3rd 方,但我还没有找到将其集成到 MVC 中的方法。

还有其他想法/解决方案吗?

谢谢。

4

3 回答 3

3

鉴于您的其他详细信息,您应该能够使用任意数量的工具来执行此操作。CodeCaster 的想法很好,PhantomJS 也提供了类似的基于 webkit 的任意 url 图像生成(https://github.com/ariya/phantomjs/wiki/Screen-Capture)。它提供了多种输出格式选项,例如 PNG、JPG、GIF 和 PDF。

由于 PhantomJS 使用的是 WebKit,一个真正的布局和渲染引擎,它可以捕获网页作为屏幕截图。因为 PhantomJS 可以渲染网页上的任何内容,所以它不仅可以用于转换 HTML 和 CSS 格式的内容,还可以用于转换 SVG 和 Canvas 格式的内容。

您需要从您的 MVC 应用程序执行 phantomjs.exe 应用程序,或者可能更好地通过在后台运行的某些服务来处理提交的 url 队列。

于 2013-06-27T17:08:33.367 回答
1

为什么要将它集成到 MVC 中?截取其他网站的截图是您网站的责任吗?我会选择在单独的库中创建截屏逻辑,例如作为 Windows 服务托管。

控件需要在WebBrowser服务(如 IIS)没有的 UI 线程上运行。您可以尝试其他库。

例如,您可以围绕wkhtmltopdf编写一些代码,它使用 WebKit 引擎将 HTML 呈现(正如其名称可能暗示的那样)到 PDF。

于 2013-06-27T15:48:41.137 回答
1

您需要指定线程处于 STA(单线程单元模式以实例化 Web 浏览器)。

public ActionResult Save()
{
    var url = "http://www.google.co.uk";

    FileContentResult result = null;
    Bitmap bitmap = null;

    var thread = new Thread(
    () =>
    {
        bitmap = ExportUrlToImage(url, 1280, 1024);
    });

    thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
    thread.Start();
    thread.Join();

    if (bitmap != null)
    {
        using (var memstream = new MemoryStream())
        {
            bitmap.Save(memstream, ImageFormat.Jpeg);
            result = this.File(memstream.GetBuffer(), "image/jpeg");
        }
    }

    return result;
}

private Bitmap ExportUrlToImage(string url, int width, int height)
{
    // Load the webpage into a WebBrowser control
    WebBrowser wb = new WebBrowser();
    wb.ScrollBarsEnabled = false;
    wb.ScriptErrorsSuppressed = true;

    wb.Navigate(url);
    while (wb.ReadyState != WebBrowserReadyState.Complete)
    {
            Application.DoEvents();
    }

    // Set the size of the WebBrowser control
    wb.Width = width;
    wb.Height = height;

    Bitmap bitmap = new Bitmap(wb.Width, wb.Height);
    wb.DrawToBitmap(bitmap, new System.Drawing.Rectangle(0, 0, wb.Width, wb.Height));
    wb.Dispose();

    return bitmap;
}
于 2015-10-26T12:21:30.870 回答