使用 C# 将 html 转换为带有分页的图像

本文关键字:分页 图像 html 转换 使用 | 更新日期: 2023-09-27 18:33:21

我正在 c# 4.0 中开发一个 Windows 服务,在图像中转换不同的文件(tif 和 jpeg(

当我想在图像中转换html文件(通常是电子邮件(时,我遇到了问题。

我使用网络浏览器

var browser = new WebBrowser();
browser.DocumentCompleted += this.BrowserDocumentCompleted;
browser.DocumentText = html;

和绘制到位图

var browser = sender as WebBrowser;
Rectangle body = new Rectangle(browser.Document.Body.ScrollRectangle.X * scaleFactor,
    browser.Document.Body.ScrollRectangle.Y * scaleFactor,
    browser.Document.Body.ScrollRectangle.Width * scaleFactor,
    browser.Document.Body.ScrollRectangle.Height * scaleFactor);
browser.Height = body.Height;
Bitmap output = new Bitmap(body.Width, body.Height);
browser.DrawToBitmap(output, body);

它适用于小型或中型 html,但适用于长 html(如 22 000 高度 px 或更高(我在DrawToBitmap上有GDI扩展:

  • 参数无效

  • 不是 GDI+ 有效的图像

根据互联网的说法,这种错误是因为图像太大而附加的。

我的问题:如何在不生成大图像和裁剪的情况下转换 X 图像(分页(中的 html,以及是否可以不使用库。

提前谢谢你。

编辑:我找到了一个棘手的解决方案:用一个div女巫来设置页面,另一个用于偏移量,例如:

<div style="height:3000px; overflow:hidden"> 
<div style="margin-top:-3000px">

但是这个解决方案可以在一行文本上或图像中间裁剪......

使用 C# 将 html 转换为带有分页的图像

您可以尝试创建自定义 IE 打印模板,并使用 DEVICERECT 和 LAYOUTRECT 元素来驱动分页。然后,这些线条不会被剪切到中间,您可以将每个DEVICERECT的位图捕获为页面。您需要向 MSHTML 文档对象发出 CGID_MSHTML/IDM_SETPRINTTEMPLATE 命令 ( webBrowser.Document.DomDocument as IOleCommandTarget ( 以启用特定于打印模板的元素标记,例如这些。有关打印模板的更多信息,请参阅此处。

甚至可以在DEVICERECT对象上使用IHTMLElementRender::D rawToDC API在位图DC上绘制其内容。您需要启用FEATURE_IVIEWOBJECTDRAW_DMLT9_WITH_GDI并禁用FEATURE_GPU_RENDERING功能控制设置,以便您的WebBrowser托管应用程序使用 IHTMLElementRender::DrawToDC

谢谢你的鼻子比。

我通过使用打印和虚拟打印机来获取图像文件来建立一个解决方案。

将 html 保存在文件中并删除所有编码:

html = Regex.Replace(html, "<meta[^>]*http-equiv='"Content-Type'"[^>]*>", string.Empty, RegexOptions.Multiline);
using (var f = File.Create(filePath))
{
   var bytes = Encoding.Default.GetBytes(html);
   f.Write(bytes, 0, bytes.Length);
}

运行打印而不显示网络浏览器和打印弹出窗口:

const short PRINT_WAITFORCOMPLETION = 2;
const int OLECMDID_PRINT = 6;
const int OLECMDEXECOPT_DONTPROMPTUSER = 2;
dynamic ie = browser.ActiveXInstance;
ie.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, PRINT_WAITFORCOMPLETION);

我使用PDFCreator进行虚拟打印,它将我的所有文件保存在一个文件夹中。获取所有这些文件并不容易(知道打印何时完成,有多少文件以及何时可以使用它们......(,但这不是这篇文章的目的!