我正在努力寻找一种在MVC4中截取网站截图的方法。我已经看到了两种可能的解决方案,它们对MVC都不起作用。
第一个是使用WebBrowser,找到here教程,但这会给我一个ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment
错误。
另一方正在使用名为Grabz.It的第三方,但我还没有找到将其集成到MVC中的方法。
还有其他想法/解决方案吗?
感谢。
答案 0 :(得分: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队列。
答案 1 :(得分:1)
为什么希望将其集成到MVC中? 您的网站是否有责任截取其他网站的屏幕截图?我会选择在一个单独的库中创建截屏逻辑,例如托管为Windows服务。
WebBrowser
控件需要在UI线程上运行,而服务(如IIS)没有。您可以尝试其他库。
例如,您可以在wkhtmltopdf周围编写一些代码,使用WebKit引擎将HTML呈现为PDF(如名称所暗示的那样)。
答案 2 :(得分: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;
}