あなたの場合content
、ページを構成する生のHTMLであり、レンダリング方法ではありません。これは、ベース64(これは、 ASCII文字のみを使用してバイナリデータをエンコードする方法)、これを機能させるには、JPEGエンコード画像のbase 64エンコードバイナリデータを取得する必要がありますが、ブラウザはHTMLをレンダリングしますが、これはありません。
サーバー上で実行している.netコードでは、スクリーンショットを撮ることができるものにHTMLをレンダリングするのはクライアントの仕事であるため、これをWebアプリケーションで実現するのは簡単ではないと思います。サーバーでブラウザーコントロールを使用することはできます(これはおそらく非常に壊れやすいので、あまりお勧めしません。このようなwinformsコントロールをWebアプリケーションでホストすることは、通常、問題のレシピですが、可能かもしれません) 。サイドとそのURLを設定しますが、それからどういうわけかそれをスクリーンショットする必要があります-これは役立つかもしれません:WebBrowserコントロールでウェブサイトのスクリーンショットを撮る。
アップデート
最後にリンクしたWebサイトのコメントに隠れているのは、(WebBrowserコントロールを使用して)Webページのスクリーンショットを撮るために実際に機能するコードです。以下への参照が必要です。
- System.Drawing
- System.Windows.Forms
- Microsoft HTMLオブジェクトライブラリ(これはCOMリファレンスであり、.NETのものではありません)
これが私たちが望む仕事をするクラスです(UriとSizeを取り、ビットマップを返す単一のRenderメソッドがあります):
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アプリケーションが実行されているアカウントになることを意味します。
OK、それで、上記はwinformsアプリでは問題ないと思いますが、Webには適切ではないかもしれませんが、とにかくそれを機能させることができます、ここに行きます...
通常のASP.NETWebアプリケーションを使用することを想定しています。その場合、.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のスクリーンショットが含まれています。