将 HTML 字符串转换为图像

Posted

技术标签:

【中文标题】将 HTML 字符串转换为图像【英文标题】:Convert HTML string to image 【发布时间】:2013-07-23 19:52:38 【问题描述】:

我有一个包含 html 标记的字符串变量。这个 HTML 标记基本上代表了电子邮件的内容。

现在我想从这个字符串内容创建一个实际包含 HTML 标记的图像。 我不想通过将此内容写入其中来创建 HTML 文件。我只想用这个字符串创建一个图像文件。

这是我所拥有的:

string emailBody="<html><head></head><body><p>This is my text<p>...</body</html>"

如何从这个emailBody 字符串内容创建图像?

【问题讨论】:

复制:***.com/questions/10721884/render-html-to-an-image 你需要http://htmlrenderer.codeplex.com/之类的东西吗? 感谢@AlexFilipovici。我对此进行了调查,并且还找到了有关此的帖子。但我只想知道是否有任何本机代码可用于此..如果没有找到其他任何方法,我将使用它。 amoghnatu.wordpress.com/2013/05/13/… @KeesDeWit - 这个问题似乎集中在客户端渲染(在浏览器中),而这个问题需要浏览器之外的代码。 【参考方案1】:

感谢大家的回复。我使用HtmlRenderer 外部dll(库)来实现相同的功能,并在code 下方找到了相同的功能。

这是代码

public void ConvertHtmlToImage()

   Bitmap m_Bitmap = new Bitmap(400, 600);
   PointF point = new PointF(0, 0);
   SizeF maxSize = new System.Drawing.SizeF(500, 500);
   HtmlRenderer.HtmlRender.Render(Graphics.FromImage(m_Bitmap),
                                           "<html><body><p>This is some html code</p>"
                                           + "<p>This is another html line</p></body>",
                                            point, maxSize);

   m_Bitmap.Save(@"C:\Test.png", ImageFormat.Png);

【讨论】:

为什么这个答案没有得到更多的支持?对我来说几乎完美无缺(除了我必须对图像分辨率进行一些微调)? 使用 HtmlRenderer.HtmlRender.RenderGdiPlus 代替,否则看起来不太好。 我尝试使用上述引用 htmlrenderer 程序集的代码。但它不起作用。无法识别程序集。我尝试将命名空间用作“使用 TheArtOfDev.HtmlRenderer” subash,你还需要添加HtmlRenderer,WinForms 然后使用TheArtOfDev.HtmlRenderer.WinForms.HtmlRender.RenderToImage 我在我的asp.net web应用程序中添加了HtmlRenderer.Core dll,但没有可用的HtmlRenderer.HtmlRender.Render方法。【参考方案2】:

尝试以下方法:

using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;

class Program

    static void Main(string[] args)
    
        var source =  @"
        <!DOCTYPE html>
        <html>
            <body>
                <p>An image from W3Schools:</p>
                <img 
                    src=""http://www.w3schools.com/images/w3schools_green.jpg"" 
                    W3Schools.com"" 
                    104"" 
                    142"">
            </body>
        </html>";
        StartBrowser(source);
        Console.ReadLine();
    

    private static void StartBrowser(string source)
    
        var th = new Thread(() =>
        
            var webBrowser = new WebBrowser();
            webBrowser.ScrollBarsEnabled = false;
            webBrowser.DocumentCompleted +=
                webBrowser_DocumentCompleted;
            webBrowser.DocumentText = source;
            Application.Run();
        );
        th.SetApartmentState(ApartmentState.STA);
        th.Start();
    

    static void 
        webBrowser_DocumentCompleted(
        object sender, 
        WebBrowserDocumentCompletedEventArgs e)
    
        var webBrowser = (WebBrowser)sender;
        using (Bitmap bitmap = 
            new Bitmap(
                webBrowser.Width, 
                webBrowser.Height))
        
            webBrowser
                .DrawToBitmap(
                bitmap, 
                new System.Drawing
                    .Rectangle(0, 0, bitmap.Width, bitmap.Height));
            bitmap.Save(@"filename.jpg", 
                System.Drawing.Imaging.ImageFormat.Jpeg);
        
    

注意:感谢 Hans Passant 他在问题 WebBrowser Control in a new thread 上的出色表现 answer 启发了这个解决方案。

【讨论】:

这对我来说已经很长时间了。刚刚发现了一个限制。在 css 中通过 @font-face 访问的下载字体不会被渲染。 我不相信这在 .net 核心中可用。它似乎只在框架中 @Paul Evans 你有没有找到可以解决这个问题的解决方案? 简单的概念!有谁知道如何扩展此解决方案,以将整个页面放入输出图像中,即使页面的高度大于图像的高度?【参考方案3】:

所以我想到了这个,我想我会将我的最新解决方案发布给任何搜索类似内容的人。

我使用了(开源)Puppeteer Sharp (v3) 结果如下所示:

public class ImageRenderer : IDisposable
    
        private BrowserFetcher _browserFetcher;

        public ImageRenderer()
        
            _browserFetcher = new BrowserFetcher();
        

        public async Task<byte[]> RenderImageDataAsync(string html)
        
            try
            
                // Download chrome (headless) browser (first time takes a while).
                await _browserFetcher.DownloadAsync();

                // Launch the browser and set the given html.
                await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions  Headless = true );
                await using var page = await browser.NewPageAsync();
                await page.SetContentAsync(html);

                // Select the element and take a screen-shot, or just use the page, for example: page.ScreenshotDataAsync()
                var elementQuery = "#myElementId";
                await page.WaitForSelectorAsync(elementQuery, new WaitForSelectorOptions  Timeout = 2000 ); // Wait for the selector to load.

                var elementHandle = await page.QuerySelectorAsync(elementQuery); // Declare a variable with an ElementHandle.
                var result = await elementHandle.ScreenshotDataAsync(
                    new ScreenshotOptions
                    
                        Type = ScreenshotType.Png
                        // Quality = Not supported with PNG images!
                    
                );

                await browser.CloseAsync();
                return result;
            
            catch (Exception ex)
            
                // Log ex $"nameof(RenderImageDataAsync): Unable to render image from nameof(html)=html");
            

            return null;
        

        public void Dispose()
        
            _browserFetcher = null;
        
    
专业版:使用真正的浏览器; 缺点:使用真正的浏览器; _browserFetcher.DownloadAsync(); 将为此下载(到文件夹 .local-chromium)大约 380MB 的文件。

【讨论】:

【参考方案4】:
       <!--ForExport data in iamge -->
        <script type="text/javascript">
            function ConvertToImage(btnExport) 
                html2canvas($("#dvTable")[0]).then(function (canvas) 
                    var base64 = canvas.toDataURL();
                    $("[id*=hfImageData]").val(base64);
                    __doPostBack(btnExport.name, "");
                );
                return false;
            
        </script>

        <!--ForExport data in iamge -->

        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
        <script src="../js/html2canvas.min.js"></script> 





<table>
                <tr>
                    <td valign="top">
                        <asp:Button ID="btnExport" Text="Download Back" runat="server" UseSubmitBehavior="false"
                            OnClick="ExportToImage" OnClientClick="return ConvertToImage(this)" />
                        <div id="dvTable" class="divsection2" style="width: 350px">
                            <asp:HiddenField ID="hfImageData" runat="server" />
                            <table >
                                <tr>
                                    <td>
                                        <br />

                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        <asp:Label ID="Labelgg" runat="server" CssClass="labans4" Text=""></asp:Label>
                                    </td>
                                </tr>

                            </table>
                        </div>
                    </td>
                </tr>
            </table>


         protected void ExportToImage(object sender, EventArgs e)
                
                    string base64 = Request.Form[hfImageData.UniqueID].Split(',')[1];
                    byte[] bytes = Convert.FromBase64String(base64);
                    Response.Clear();
                    Response.ContentType = "image/png";
                    Response.AddHeader("Content-Disposition", "attachment; filename=name.png");
                    Response.Buffer = true;
                    Response.Cache.SetCacheability(HttpCacheability.NoCache);
                    Response.BinaryWrite(bytes);
                    Response.End();

                

【讨论】:

OP 显然是在寻求一种在 C# ASP.Net 中实现它的方法,而不是在浏览器中。

以上是关于将 HTML 字符串转换为图像的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中将 HTML 字符串转换为图像 [关闭]

将ZPL字符串转换为JPG图像和PDF

将图像转换为字符串的数据大小

如何将图像转换为 Base64 字符串,并转换回图像,保存到 azure blob

Openxml单词插入图像

将php字符串转换为图像