在您的情况下content
,是构成页面的原始 HTML,而不是如何呈现页面 - 这将由浏览器决定(在调试器中查看它)所以,因为这不是base 64(这是仅使用 ASCII 字符对二进制数据进行编码的方法),为了使其工作,您需要获取 JPEG 编码图像的 base 64 编码二进制数据,但浏览器已呈现您没有的 HTML。
我认为这在 Web 应用程序中实现起来并不容易,因为在您在服务器上运行的 .net 代码中,客户端的工作是将 HTML 呈现为您可以截屏的内容。你可以(这可能真的很脆弱,所以我不会真的推荐它,在 Web 应用程序中托管这样的 winforms 控件通常会带来麻烦,但我认为它可能)在你的服务器上使用浏览器控件侧面并设置它的 URL,但是您需要以某种方式对其进行截图 - 这可能会有所帮助:使用 WebBrowser 控件拍摄网站截图。
更新
在我最后链接的网站的评论中隐藏了一些代码,这些代码实际上可以截取网页的屏幕截图(使用 WebBrowser 控件)。它要求您参考以下内容:
- 系统绘图
- System.Windows.Forms
- Microsoft HTML 对象库(这是一个 COM 引用,而不是 .NET 引用)
这是一个完成我们想要的工作的类(它只有一个 Render 方法,它接受一个 Uri 和一个 Size 并返回一个 Bitmap):
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using mshtml;
public class HtmlToBitmapConverter
{
public Bitmap Render(Uri uri, Size size)
{
var browser = new WebBrowser
{
ScrollBarsEnabled = false,
ScriptErrorsSuppressed = true,
Size = size
};
browser.BringToFront();
NavigateAndWaitForLoad(browser, uri, 0);
var bitmap = new Bitmap(size.Width, size.Height);
GetImage(browser.Document.DomDocument, bitmap, Color.White);
return bitmap;
}
private void NavigateAndWaitForLoad(WebBrowser browser,
Uri uri,
int waitTime)
{
const int sleepTimeMiliseconds = 5000;
browser.Navigate(uri);
var count = 0;
while (browser.ReadyState != WebBrowserReadyState.Complete)
{
Thread.Sleep(sleepTimeMiliseconds);
Application.DoEvents();
count++;
if (count > waitTime / sleepTimeMiliseconds)
{
break;
}
}
while (browser.Document.Body == null)
{
Application.DoEvents();
}
var document = (IHTMLDocument2)browser.Document.DomDocument;
var style = (IHTMLStyle2)document.body.style;
style.overflowX = "hidden";
style.overflowY = "hidden";
}
private static void GetImage(object obj,
Image destination,
Color backgroundColor)
{
using (var graphics = Graphics.FromImage(destination))
{
var deviceContextHandle = IntPtr.Zero;
var rectangle = new Rect
{
Right = destination.Width,
Bottom = destination.Height
};
graphics.Clear(backgroundColor);
try
{
deviceContextHandle = graphics.GetHdc();
var viewObject = (IViewObject)obj;
viewObject.Draw(1,
-1,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
deviceContextHandle,
ref rectangle,
IntPtr.Zero,
IntPtr.Zero,
0);
}
finally
{
if (deviceContextHandle != IntPtr.Zero)
{
graphics.ReleaseHdc(deviceContextHandle);
}
}
}
}
[ComImport]
[Guid("0000010D-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IViewObject
{
void Draw([MarshalAs(UnmanagedType.U4)] uint dwAspect,
int lindex,
IntPtr pvAspect,
[In] IntPtr ptd,
IntPtr hdcTargetDev,
IntPtr hdcDraw,
[MarshalAs(UnmanagedType.Struct)] ref Rect lprcBounds,
[In] IntPtr lprcWBounds,
IntPtr pfnContinue,
[MarshalAs(UnmanagedType.U4)] uint dwContinue);
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct Rect
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
}
注意正如我之前所说,我不确定在 Web 应用程序中使用这是否是一个好主意,原因如下:
- 它是一个 Windows 窗体控件,因此它处理内存的方式可能与在 Web 应用程序中使用的方式不兼容。
- 这意味着截取屏幕截图的帐户将是运行 Web 应用程序的帐户,不一定是最终用户。
好的,所以我认为以上内容在 winforms 应用程序中会很好,但可能不适合网络,但是,嘿,无论如何我们都可以让它工作,这里......
我假设您要使用常规的 ASP .NET Web 应用程序,在这种情况下,您将在 .aspx 页面中有类似的内容:
<asp:Button runat="server" OnClick="TakeScreenShot" Text="Take Screenshot"/>
然后在 TakeScreenshot 方法后面的代码中将如下所示:
protected void TakeScreenShot(object sender, EventArgs e)
{
Uri uri = new Uri("http://www.google.com");
// Because it is a WebBrowser control it needs to run in an STA
// thread - what we will do is render the image to a Bitmap then
// store the raw bytes in this byte array from a newly created
// thread
byte[] screenshot = null;
var t = new Thread(() =>
{
using (var ms = new MemoryStream())
{
// The screenshot object contains a 640x480
// screenshot
var bitmap = new HtmlToBitmapConverter()
.Render(uri,
new Size(640, 480));
bitmap.Save(ms, ImageFormat.Jpeg);
screenshot = ms.ToArray();
}
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
// Here we have the JPEG encoded bytes of the image - we can
// just save them to a file like so...
using (var f = File.Create(@"c:\google.jpg"))
{
f.Write(screenshot, 0, screenshot.Length);
}
}
好了 - c:\google.jpg 将在其中包含 Google 的屏幕截图。