【问题标题】:Convert html to image with pagination using C#使用 C# 将 html 转换为带有分页的图像
【发布时间】:2013-10-06 02:36:48
【问题描述】:

我正在使用 c# 4.0 开发 Windows 服务,它可以转换图像中的不同文件(tif 和 jpeg)

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

我使用浏览器

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

和DrawToBitmap

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 像素或更高) 我在 DrawToBitmap 上有 GDI 例外:

  • 参数无效

  • 图像 GDI+ 无效

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

我的问题:如何在 X 图像(分页)中转换 html 而不生成大图像并在之后裁剪,以及是否可以不使用库。

提前谢谢你。

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

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

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

【问题讨论】:

    标签: c# pagination webbrowser-control gdi+


    【解决方案1】:

    您可以尝试创建自定义IE Print Template 并使用DEVICERECTLAYOUTRECT 元素来驱动分页。那时,线条不会在中间被剪断,您可以将每个DEVICERECT 的位图捕获为一页。您需要向 MSHTML 文档对象 (webBrowser.Document.DomDocument as IOleCommandTarget) 发出 CGID_MSHTML/IDM_SETPRINTTEMPLATE 命令,以启用此类打印模板特定元素标签。有关打印模板的更多信息,请访问here

    [EDITED]您甚至可以在DEVICERECT 对象上使用IHTMLElementRender::DrawToDC API 在位图DC 上绘制其内容。您需要为您的WebBrowser 托管应用启用FEATURE_IVIEWOBJECTDRAW_DMLT9_WITH_GDI 并禁用FEATURE_GPU_RENDERING feature control settings 才能使用IHTMLElementRender::DrawToDC

    【讨论】:

      【解决方案2】:

      感谢您的 anwser Noseratio。

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

      将 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 进行虚拟打印,它将所有文件保存在一个文件夹中。获取所有这些文件并不容易(知道何时打印完成、有多少文件以及何时可以使用它们......)但这不是本文的目的!

      【讨论】:

        猜你喜欢
        • 2015-05-05
        • 1970-01-01
        • 1970-01-01
        • 2018-05-06
        • 2017-12-30
        • 1970-01-01
        • 2013-02-24
        • 1970-01-01
        • 2019-12-16
        相关资源
        最近更新 更多