WebBrowser screenshot html on ASP.NET
前言
以往都認為WebBrowser沒辦法在ASP.NET中使用,最近不小心解出來,記錄一下
前置作業
WebBrowser的Navigate方法貌似導向https網頁(自簽憑證SSL)會出錯,我的替代方式改先用WebClient把網頁Html字串抓下來再餵給WebBrowser來轉出圖片
我工作上的專案是.Net 3.5,所以使用WebClient,如果你的工作專案.Net Framework版本是.Net 4.5以上的話,建議改用HttpClient比較好
如果你的程式版本是.Net 3.5以下,主機可能要安裝下述hotfix,程式才能支援TLS1.2的通訊協定(WebClient、HttpClient、HttpRequest這些物件遠端呼叫時會用到)
程式碼實作
先自己寫一個類別 MyWebUtility.cs↓
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Web;
using System.Windows.Forms;
public class MyWebUtily
{
/// <summary>
/// 用IE核心來截圖網頁
/// </summary>
/// <param name="url">目標網址</param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="gifFilePath">gif檔案路徑</param>
public static void webBrowser_ScreenShotToGif(string url, string gifFilePath, int width, int height)
{
Thread th = new Thread(() =>
{
//略過https驗證錯誤
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, error) => { return true; };
//讓 WebClient、HttpClient 走 TLS 1.2 協定
//.Net 3.5寫法↓
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
//.Net 4.5寫法↓
// ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//建立 WebClient
string htmlContent = "";//網頁回傳html字串
using (WebClient client = new WebClient())
{
client.Encoding = Encoding.UTF8;
htmlContent = client.DownloadString(url);
}
WebBrowser wb = new WebBrowser()
{
ScrollBarsEnabled = false,
IsWebBrowserContextMenuEnabled = false,
AllowNavigation = true,
ScriptErrorsSuppressed = true,
DocumentText = htmlContent//html字串
};
wb.DocumentCompleted += (sender, ee) =>
{
WebBrowser webBrowser = (WebBrowser)sender;
if (width == 0)//呼叫端給0
{//預設值
width = webBrowser.Document.Body.ScrollRectangle.Width+100;//加100自己微調
}
if (height == 0)
{
height = webBrowser.Document.Body.ScrollRectangle.Height;
}
webBrowser.Width = width;
webBrowser.Height = height;
using (Bitmap bitmap = new Bitmap(width, height))//準備畫布
{//webBrowser截圖至畫布
webBrowser.DrawToBitmap(bitmap, new Rectangle(0, 0, width, height));
bitmap.Save(gifFilePath, ImageFormat.Gif);//低品質圖片儲存法,將就使用XD
}
};
//Console.WriteLine(wb.ReadyState.ToString());//debug
while (wb.ReadyState != WebBrowserReadyState.Complete) { System.Windows.Forms.Application.DoEvents(); }
//Console.WriteLine(wb.ReadyState.ToString());//debug
wb.Dispose();
});
th.SetApartmentState(ApartmentState.STA); /*因為用到WebBrowser,所以加上STA*/
th.Start();
th.Join();//執行緒做完才能下個動作
}
}
在 *.aspx.cs中的叫用方法↓
using System;
using System.Configuration;
public partial class GifTest : System.Web.UI.Page
{
string WebBaseUrl = ConfigurationManager.AppSettings["WebBaseUrl"];
/// <summary>
/// 依自己情況修改↓
/// </summary>
string PathGif = @"S:\CoverPage-"+DateTime.Now.ToString("yyyyMMddHHmmss")+".gif";//產出的gif檔案路徑
//WebBrowser的width、height
readonly int width = 1000;//固定寬
readonly int height = 0;//自適應高
protected void Page_Load(object sender, EventArgs e)
{
string gifUrl = "https://www.pchome.com.tw/";
//網頁截圖並儲存在主機上
MyWebUtily.webBrowser_ScreenShotToGif(gifUrl, PathGif,this.width, this.height);
}
}
文章參考
How to render Html content into JPG/JPEG image in best quality (WinForms)
Convert a specific part of html to image using WebBrowser