【问题标题】:Render HTML to an image将 HTML 渲染为图像
【发布时间】:2012-05-30 02:46:56
【问题描述】:

有没有办法将 html 渲染成像 PNG 这样的图像?我知道画布是可能的,但我想渲染标准的 html 元素,例如 div。

【问题讨论】:

  • 例如创建某种用户帮助。可悲的是,这是不可能的(出于安全原因?)。您必须要求用户按 PrintScreen 才能执行某项操作。
  • 我想用 HTML/CSS 来设计一个 logo。
  • @ErnestFriedman-Hill 不是重复的:你提到的问题是 java 特有的。
  • 每个人都知道这在服务器端是可能的。这相当于回答“什么是 2+2?”与“5 接近您正在寻找的,但它有点令人费解。”

标签: javascript html css image render


【解决方案1】:

我也关注这个问题。 我发现这是解决您问题的最佳解决方案

我们可以使用html-to-image javascript库将HTML代码转换为图像

npm install html-to-image

HTML 代码

<div>
<div id="capture">
 <p>
    <span>Heading Of Image</span><br></br>
    <span>This is color Image</span><br></br>
    <img src="Your/ImagePath/ifany.jpg" width="100%" />
    <span>Footer Of the Image</span>
 </p>
</div>
<h2>Generated Image</h2>
<div id="real">
</div></div>

Javascript 代码

var htmlToImage = require('html-to-image');
var node = document.getElementById('capture');
htmlToImage.toJpeg(node, { quality: 1, backgroundColor: "#FFFFFF", height: node.clientHeight, width: node.clientWidth })
    .then(function (dataUrl) {
        var img = new Image();
        img.src = dataUrl;
        var div = document.getElementById("real")
        div.appendChild(img)
    })
    .catch(function (error) {
        console.error('oops, something went wrong!', error);
    });

通过此示例,您现在可以在&lt;div&gt; 标签中看到您的图像,其中id = 'real'。 您现在可以在代码中添加保存和下载或上传图片选项。

【讨论】:

    【解决方案2】:

    有很多选择,它们都有自己的优点和缺点。

    选项 1:使用 API

    优点

    • 执行 Javascript
    • 近乎完美的渲染
    • 正确使用缓存选项时速度快
    • 规模由 API 处理
    • 精确计时、视口...
    • 他们大多提供免费计划

    缺点

    • 如果您打算大量使用它们,则不是免费的

    选项 2:使用众多可用库之一

    优点

    • 大部分时间转换速度都很快

    缺点

    • 渲染错误
    • 不执行 javascript
    • 不支持最近的 Web 功能(FlexBox、高级选择器、Webfonts、Box Sizing、媒体查询等)
    • 有时安装起来并不容易
    • 规模复杂

    选项 3:使用 PhantomJs 和可能的包装库

    优点

    • 执行 Javascript
    • 相当快

    缺点

    • 渲染错误
    • 不支持最近的 Web 功能(FlexBox、高级选择器、Webfonts、Box Sizing、媒体查询等)
    • 规模复杂
    • 如果有要加载的图像,让它工作就不是那么容易了......

    选项 4:使用 Chrome Headless,也可以使用包装库

    优点

    • 执行 Javascript
    • 近乎完美的渲染

    缺点

    • 要获得关于以下方面的确切结果并不容易:
      • 页面加载时间
      • 视口尺寸
    • 规模复杂
    • 如果 html 包含外部链接,速度会很慢,甚至更慢

    披露:我是 ApiFlash 的创始人。我尽力提供一个诚实而有用的答案。

    【讨论】:

    • wkhtmltoimage/pdf 确实支持 javascript 渲染。您可以设置 javascript 延迟或让 wkhtml 检查特定的 window.status(当您知道您的 js 工作完成时,您可以使用 javascript 设置)
    • PhantomJS 支持动态的东西,比如谷歌地图。它实际上是一个完整的网络浏览器,只是没有附加显示器。但是,您必须稍等片刻才能让 Google Map 加载带有地理信息的图块(我等待 500 毫秒并允许人们更改延迟 - 如果还不够,在不增加时间的情况下再次运行就可以了,因为这些图块已缓存)。
    【解决方案3】:

    这就是我所做的。

    注意:代码请查看 App.js。

    Link to source code

    如果你喜欢它,你可以给它一个星星。✌️

    更新

    import * as htmlToImage from 'html-to-image';
    import download from 'downloadjs';
    
    import logo from './logo.svg';
    import './App.css';
    
    const App = () => {
      const onButtonClick = () => {
        var domElement = document.getElementById('my-node');
        htmlToImage.toJpeg(domElement)
          .then(function (dataUrl) {
            console.log(dataUrl);
            download(dataUrl, 'image.jpeg');
          })
          .catch(function (error) {
            console.error('oops, something went wrong!', error);
          });
      };
      return (
        <div className="App" id="my-node">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <p>
              Edit <code>src/App.js</code> and save to reload.
            </p>
            <a
              className="App-link"
              href="https://reactjs.org"
              target="_blank"
              rel="noopener noreferrer"
            >
              Learn React
            </a><br></br>
            <button onClick={onButtonClick}>Download as JPEG</button>
          </header>
        </div>
      );
    }
    
    export default App;
    

    【讨论】:

    【解决方案4】:

    我阅读了 Sjeiti 的答案,我觉得这很有趣,您只需几行纯 JavaScript 行就可以在图像中呈现 HTML。

    我们当然必须意识到这种方法的局限性(请在他的回答中阅读其中的一些)。

    在这里,我将他的代码更进一步。

    SVG 图像原则上具有无限分辨率,因为它是矢量图形。但是您可能已经注意到,Sjeiti 的代码生成的图像没有高分辨率。这可以通过在将 SVG 图像传输到画布元素之前对其进行缩放来解决,我在下面给出的两个(可运行)示例代码中的最后一个中完成了这一点。我在该代码中实现的另一件事是最后一步,即将其保存为 PNG 文件。只是为了完成整个事情。

    所以,我给出两个可运行的 sn-ps 代码:

    第一个演示了 SVG 的无限分辨率。运行它并使用浏览器放大,看看分辨率不会随着放大而降低。

    在您可以运行的 sn-p 中,我使用反引号指定了一个带有换行符的所谓模板字符串,以便您可以更清楚地看到呈现的 HTML。但是否则,如果该 HTML 在一行之内,那么代码将非常短,就像这样。

    const body = document.getElementsByTagName('BODY')[0];
    const img = document.createElement('img')
    img.src = 'data:image/svg+xml,' + encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml" style="border:1px solid red;padding:20px;"><style>em {color:red;}.test {color:blue;}</style>What you see here is only an image, nothing else.<br /><br /><em>I</em> really like <span class="test">cheese.</span><br /><br />Zoom in to check the resolution!</div></foreignObject></svg>`);        
    body.appendChild(img);
    

    这里是一个可运行的 sn-p。

    const body = document.getElementsByTagName('BODY')[0];
    const img = document.createElement('img')
    img.src = 'data:image/svg+xml,' + encodeURIComponent(`
      <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
        <foreignObject width="100%" height="100%">
          <div xmlns="http://www.w3.org/1999/xhtml" style="border:1px solid red;padding:20px;">
            <style>
              em {
                color:red;
              }
              .test {
                color:blue;
              }
            </style>
            What you see here is only an image, nothing
            else.<br />
            <br />
            <em>I</em> really like <span class="test">cheese.</span><br />
            <br />
            Zoom in to check the resolution!
          </div>
        </foreignObject>
      </svg>
    `);
    body.appendChild(img);

    放大并检查 SVG 的无限分辨率。

    下面的下一个可运行文件实现了我上面提到的两个额外步骤,即通过首先缩放 SVG 来提高分辨率,然后将其保存为 PNG 图像。

    window.addEventListener("load", doit, false)
    var canvas;
    var ctx;
    var tempImg;
    function doit() {
        const body = document.getElementsByTagName('BODY')[0];
        const scale = document.getElementById('scale').value;
        let trans = document.getElementById('trans').checked;
      if (trans) {
        trans = '';
      } else {
        trans = 'background-color:white;';
      }
        let source = `
            <div xmlns="http://www.w3.org/1999/xhtml" style="border:1px solid red;padding:20px;${trans}">
                <style>
                    em {
                        color:red;
                    }
                    .test {
                        color:blue;
                    }
                </style>
                What you see here is only an image, nothing
                else.<br />
                <br />
                <em>I</em> really like <span class="test">cheese.</span><br />
                <br />
                <div style="text-align:center;">
                    Scaling:
                    <br />
                    ${scale} times!
                </div>
            </div>`
        document.getElementById('source').innerHTML = source;
        canvas = document.createElement('canvas');
        ctx = canvas.getContext('2d');
        canvas.width = 200*scale;
        canvas.height = 200*scale;
        tempImg = document.createElement('img');
        tempImg.src = 'data:image/svg+xml,' + encodeURIComponent(`
            <svg xmlns="http://www.w3.org/2000/svg" width="${200*scale}" height="${200*scale}">
                <foreignObject 
                    style="
                        width:200px;
                        height:200px;
                        transform:scale(${scale});
                    "
                >` + source + `
                </foreignObject>
            </svg>
        `);
    }
    function saveAsPng(){
        ctx.drawImage(tempImg, 0, 0);
        var a  = document.createElement('a');
        a.href = canvas.toDataURL('image/png');
        a.download = 'image.png';
        a.click();
    }
    <table border="0">
        <tr>
            <td colspan="2">
                The claims in the HTML-text is only true for the image created when you click the button.
            </td>
        </tr>
        <tr>
            <td width="250">
                <div id="source" style="width:200px;height:200px;">
                </div>
            </td>
            <td valign="top">
                <div>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;In this example the PNG-image will be squarish even if the HTML here on the left is not exactly squarish. That can be fixed.<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;To increase the resolution of the image you can change the scaling with this slider.
                    <div style="text-align:right;margin:5px 0px;">
                        <label style="background-color:#FDD;border:1px solid #F77;padding:0px 10px;"><input id="trans" type="checkbox" onchange="doit();" />&nbsp;&nbsp;Make it transparent</label>
                    </div>
                    <span style="white-space:nowrap;">1<input id="scale" type="range" min="1" max="10" step="0.25" value="2" oninput="doit();" style="width:150px;vertical-align:-8px;" />10&nbsp;&nbsp;<button onclick="saveAsPng();">Save as PNG-image</button></span>
                </div>
                
            </td>
        </tr>
    </table>

    尝试不同的缩放比例。例如,如果您将缩放设置为 10,那么您会在生成的 PNG 图像中获得非常好的分辨率。 我还添加了一些额外的功能:一个复选框,以便您可以根据需要使 PNG 图像透明。

    注意:

    当此脚本在 Stack Overflow 上运行时,保存按钮在 Chrome 和 Edge 中不起作用。原因就是这个https://www.chromestatus.com/feature/5706745674465280

    因此,我还将这个 sn-p 放在了适用于这些浏览器的 https://jsfiddle.net/7gozdq5v/ 上。

    【讨论】:

    • 您只是省略了任务的主要部分:转换为 PNG!您的图像是 SVG,一种可无限缩放的矢量图形格式。但这不是问题。
    • 米高梅,你是对的。看来我完全错过了这个问题的重要方面。我将尝试修复我的答案,以便它也涵盖该部分。给我一些时间。
    • 米高梅,所以,我现在已经修好了。
    • @Magnus 我真的很喜欢这个解决方案。我自己测试并尝试将背景图像添加到正在转换的 html 中,但发现图像本身在转换时不会呈现为背景。关于如何解决的任何想法?这是我尝试过的&lt;div xmlns="http://www.w3.org/1999/xhtml" style="border:1px solid red;padding:20px;${trans};background-image: url('https://i.ibb.co/9Zvz58h/star.png')"&gt;
    • @ZakDeBrine 不幸的是,我现在无法深入研究这个问题。我建议您将其制定为一个新问题,看看您是否可以获得一些帮助。祝你好运!
    【解决方案5】:

    HtmlToImage.jar 将是将 html 转换为图像的最简单方法

    Converting HTML to image using java

    【讨论】:

    【解决方案6】:

    我知道这是一个相当古老的问题,已经有很多答案,但我仍然花了几个小时试图真正做我想做的事:

    • 给定一个 html 文件,从命令行生成一个具有透明背景的 (png) 图像

    使用无头 Chrome(版本 74.0.3729.157),实际上很容易:

    "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --headless --screenshot --window-size=256,256 --default-background-color=0 button.html
    

    命令说明:

    • 您从命令行运行 Chrome(此处显示的是 Mac,但假设在 Windows 或 Linux 上类似)
    • --headless 在不打开的情况下运行 Chrome 并在命令完成后退出
    • --screenshot 将截取屏幕截图(请注意,它会在运行命令的文件夹中生成一个名为 screenshot.png 的文件)
    • --window-size 只允许截取屏幕的一部分(格式为--window-size=width,height
    • --default-background-color=0 是告诉 Chrome 使用透明背景而不是默认白色
    • 的魔术
    • 最后您提供了 html 文件(作为本地或远程的 url...)

    【讨论】:

    • 非常好!它也适用于 SVG!我最后切换到你的解决方案! ;-)
    • --screenshot='absolute\path\of\screenshot.png' 为我工作
    • 命令行工作。如果我想从 express js 以编程方式运行它,如何运行它?
    • 仅供参考,这也适用于铬,即使它没有在手册页中提及该选项。
    • svg 对我来说不是 svg ...它只是一个带有 SVG 扩展名的 PNG ...所以要小心。
    【解决方案7】:

    这里的所有答案都使用第三方库,而在纯 Javascript 中将 HTML 渲染到图像可能相对简单。 is 在 MDN 的画布部分甚至有 an article about it

    诀窍是这样的:

    • 使用包含 XHTML 的 foreignObject 节点创建 SVG
    • 将图像的 src 设置为该 SVG 的数据 url
    • drawImage 在画布上
    • 将画布数据设置为目标image.src

    const {body} = document
    
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    canvas.width = canvas.height = 100
    
    const tempImg = document.createElement('img')
    tempImg.addEventListener('load', onTempImageLoad)
    tempImg.src = 'data:image/svg+xml,' + encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml"><style>em{color:red;}</style><em>I</em> lick <span>cheese</span></div></foreignObject></svg>')
    
    const targetImg = document.createElement('img')
    body.appendChild(targetImg)
    
    function onTempImageLoad(e){
      ctx.drawImage(e.target, 0, 0)
      targetImg.src = canvas.toDataURL()
    }

    注意事项

    • SVG 中的 HTML 必须是 XHTML
    • 出于安全原因,作为图像数据 URL 的 SVG 充当 HTML 的隔离 CSS 范围,因为无法加载外部源。因此,例如必须使用 this one 之类的工具内联 Google 字体。
    • 即使 SVG 中的 HTML 超过了图像的大小,它也会正确地绘制到画布上。但是无法从该图像中测量实际高度。 固定高度解决方案可以正常工作,但动态高度需要更多工作。最好的办法是将 SVG 数据渲染到 iframe(用于隔离的 CSS 范围)并使用画布生成的大小。

    【讨论】:

    • 不错!删除外部库依赖确实是一个好方法。我改变了我接受的答案:-)
    • 那篇文章已经不在了。
    • 很好的答案,但评论了 HTML 和 Web API 的最新技术,这和往常一样看起来像是把某人拉到后面——所有的功能在技术上都在那里,但暴露在一个数组后面(没有双关语预期的)奇怪的代码路径,与您期望从精心设计的 API 中获得的那种清晰度完全不同。简而言之:浏览器允许将Document 渲染为光栅(例如Canvas)很可能是微不足道的,但是因为没有人愿意对其进行标准化,所以我们不得不像上图那样诉诸疯狂(不冒犯此代码的作者)。
    • 这个答案stackoverflow.com/questions/12637395/… 似乎表明你可以走得很远。 Mozilla 和 Chrome 具有无限的数据 uri 长度,甚至当前的 IE 允许 4GB,归结为大约 3GB 图像(由于 base64)。但这将是一件好事。
    • -稍后进行一些快速而肮脏的测试-jsfiddle.net/Sjeiti/pcwudrmc/75965 Chrome、Edge 和 Firefox 的宽度高度至少为 10,000 像素,在这种情况下,字符数约为 10,000,000 和png 文件大小为 8MB。尚未经过严格测试,但对于大多数用例来说已经足够了。
    【解决方案8】:

    使用此代码,它肯定会工作:

    <script type="text/javascript">
     $(document).ready(function () {
    	 setTimeout(function(){
    		 downloadImage();
    	 },1000)
     });
     
     function downloadImage(){
    	 html2canvas(document.querySelector("#dvContainer")).then(canvas => {
    		a = document.createElement('a'); 
    		document.body.appendChild(a); 
    		a.download = "test.png"; 
    		a.href =  canvas.toDataURL();
    		a.click();
    	});	 
     }
    </script>

    只是不要忘记在你的程序中包含 Html2CanvasJS 文件。 https://html2canvas.hertzen.com/dist/html2canvas.js

    【讨论】:

      【解决方案9】:

      使用 html2canvas 只需包含插件和调用方法将 HTML 转换为 Canvas 然后下载为图像 PNG

              html2canvas(document.getElementById("image-wrap")).then(function(canvas) {
                  var link = document.createElement("a");
                  document.body.appendChild(link);
                  link.download = "manpower_efficiency.jpg";
                  link.href = canvas.toDataURL();
                  link.target = '_blank';
                  link.click();
              });
      

      来源http://www.freakyjolly.com/convert-html-document-into-image-jpg-png-from-canvas/

      【讨论】:

      • 请注意 html2canvas 在 Shadow dom 元素方面存在问题。如果您的应用程序正在使用 shadow dom 元素并且您希望在生成的快照中使用它,那么 html2-canvas 不是您使用 html-to-image 的好选择
      【解决方案10】:

      我为 Chrome、Firefox 和 MS Edge 工作的唯一库是 rasterizeHTML。它输出比 HTML2Canvas 更好的质量,并且与 HTML2Canvas 不同的是仍然受支持。

      获取元素并以 PNG 格式下载

      var node= document.getElementById("elementId");
      var canvas = document.createElement("canvas");
      canvas.height = node.offsetHeight;
      canvas.width = node.offsetWidth;
      var name = "test.png"
      
      rasterizeHTML.drawHTML(node.outerHTML, canvas)
           .then(function (renderResult) {
                  if (navigator.msSaveBlob) {
                      window.navigator.msSaveBlob(canvas.msToBlob(), name);
                  } else {
                      const a = document.createElement("a");
                      document.body.appendChild(a);
                      a.style = "display: none";
                      a.href = canvas.toDataURL();
                      a.download = name;
                      a.click();
                      document.body.removeChild(a);
                  }
           });
      

      【讨论】:

      • 但它不适用于 IE。 rasterizeHTML Limitations
      • @vabanagas 是否有任何单个文件 javascript 用于此?
      • 这个改变对我帮助很大:rasterizeHTML.drawHTML(node.innerHTML, canvas) 请注意,我在节点上调用了 innerHTML
      【解决方案11】:

      您可以使用PhantomJS,它是一个无头 webkit(safari 中的渲染引擎和(直到最近)chrome)驱动程序。您可以学习如何对页面here 进行屏幕截图。希望对您有所帮助!

      【讨论】:

      • 这种技术效果很好。但是,距离您发表评论已经过去了 2 年。你有没有遇到过比 PhantomJS 运行得更快的东西?根据我的经验,在 Phantom 中生成图像通常需要 2-5 秒。
      • 现在可以使用无头 Chrome。我不知道它是否更快,但是如果您想要准确的屏幕截图,这是一个不错的选择。
      【解决方案12】:

      安装 phantomjs

      $ npm install phantomjs
      

      使用以下代码创建文件 github.js

      var page = require('webpage').create();
      //viewportSize being the actual size of the headless browser
      page.viewportSize = { width: 1024, height: 768 };
      page.open('http://github.com/', function() {
          page.render('github.png');
          phantom.exit();
      });
      

      将文件作为参数传递给 phantomjs

      $ phantomjs github.js
      

      【讨论】:

        【解决方案13】:

        是的。 HTML2Canvas 用于将 HTML 渲染到 &lt;canvas&gt;(然后您可以将其用作图像)。

        注意:有一个已知问题,这不适用于 SVG

        【讨论】:

        • 这看起来很有趣,但我没能成功,所以我选择了 John Fisher 解决方案。谢谢你的信息,我以后会看这个项目的!
        • dom-to-image(参见 tsayen 的回答)在渲染准确图片方面做得更好。
        • 如果你处理的是 SVG,dom-to-image 效果更好。
        • 这个解决方案很慢
        • 另一个问题,如果元素被隐藏或在另一个元素后面,这将不起作用
        【解决方案14】:

        您可以添加参考 HtmlRenderer 到您的项目并执行以下操作,

        string htmlCode ="<p>This is a sample html.</p>";
        Image image = HtmlRender.RenderToImage(htmlCode ,new Size(500,300));
        

        【讨论】:

        • 这是一个 C# 库。该请求是针对 JavaScript 的。
        【解决方案15】:

        我可以推荐dom-to-image 库,它是专门为解决这个问题而编写的(我是维护者)。
        以下是你如何使用它(更多here):

        var node = document.getElementById('my-node');
        
        domtoimage.toPng(node)
            .then (function (dataUrl) {
                var img = new Image();
                img.src = dataUrl;
                document.appendChild(img);
            })
            .catch(function (error) {
                console.error('oops, something went wrong!', error);
            });
        

        【讨论】:

        • 这太棒了!有什么办法可以将输出大小加倍?
        • 我想到的第一件事 - 尝试将您的图像渲染为 SVG(使用 domtoimage.toSvg),然后在画布上自己渲染并尝试以某种方式使用该画布的分辨率。可能可以在库本身中实现某种渲染选项等功能,因此您可以以像素为单位传递图像尺寸。如果你需要它,我会很感激你在 github 上创建一个问题。
        • 这比 html2canvas 好多了。谢谢。
        • @Subho 这是一个字符串,包含带有 base64 编码数据的 URL
        • 是否可以使用这个库,node js服务器端本身在浏览器之前生成图像?
        【解决方案16】:

        仅使用 JavaScript 无法 100% 准确地做到这一点。

        那里有一个 Qt Webkit tool out 和一个 python version。如果你想自己做,我已经用 Cocoa 成功了:

        [self startTraverse:pagesArray performBlock:^(int collectionIndex, int pageIndex) {
        
            NSString *locale = [self selectedLocale];
        
            NSRect offscreenRect = NSMakeRect(0.0, 0.0, webView.frame.size.width, webView.frame.size.height);
            NSBitmapImageRep* offscreenRep = nil;      
        
            offscreenRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
                                                     pixelsWide:offscreenRect.size.width
                                                     pixelsHigh:offscreenRect.size.height
                                                     bitsPerSample:8
                                                     samplesPerPixel:4
                                                     hasAlpha:YES
                                                     isPlanar:NO
                                                     colorSpaceName:NSCalibratedRGBColorSpace
                                                     bitmapFormat:0
                                                     bytesPerRow:(4 * offscreenRect.size.width)
                                                     bitsPerPixel:32];
        
            [NSGraphicsContext saveGraphicsState];
        
            NSGraphicsContext *bitmapContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep];
            [NSGraphicsContext setCurrentContext:bitmapContext];
            [webView displayRectIgnoringOpacity:offscreenRect inContext:bitmapContext];
            [NSGraphicsContext restoreGraphicsState];
        
            // Create a small + large thumbs
            NSImage *smallThumbImage = [[NSImage alloc] initWithSize:thumbSizeSmall];  
            NSImage *largeThumbImage = [[NSImage alloc] initWithSize:thumbSizeLarge];
        
            [smallThumbImage lockFocus];
            [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];  
            [offscreenRep drawInRect:CGRectMake(0, 0, thumbSizeSmall.width, thumbSizeSmall.height)];  
            NSBitmapImageRep *smallThumbOutput = [[NSBitmapImageRep alloc] initWithFocusedViewRect:CGRectMake(0, 0, thumbSizeSmall.width, thumbSizeSmall.height)];  
            [smallThumbImage unlockFocus];  
        
            [largeThumbImage lockFocus];  
            [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];  
            [offscreenRep drawInRect:CGRectMake(0, 0, thumbSizeLarge.width, thumbSizeLarge.height)];  
            NSBitmapImageRep *largeThumbOutput = [[NSBitmapImageRep alloc] initWithFocusedViewRect:CGRectMake(0, 0, thumbSizeLarge.width, thumbSizeLarge.height)];  
            [largeThumbImage unlockFocus];  
        
            // Write out small
            NSString *writePathSmall = [issueProvider.imageDestinationPath stringByAppendingPathComponent:[NSString stringWithFormat:@"/%@-collection-%03d-page-%03d_small.png", locale, collectionIndex, pageIndex]];
            NSData *dataSmall = [smallThumbOutput representationUsingType:NSPNGFileType properties: nil];
            [dataSmall writeToFile:writePathSmall atomically: NO];
        
            // Write out lage
            NSString *writePathLarge = [issueProvider.imageDestinationPath stringByAppendingPathComponent:[NSString stringWithFormat:@"/%@-collection-%03d-page-%03d_large.png", locale, collectionIndex, pageIndex]];
            NSData *dataLarge = [largeThumbOutput representationUsingType:NSPNGFileType properties: nil];
            [dataLarge writeToFile:writePathLarge atomically: NO];
        }];
        

        希望这会有所帮助!

        【讨论】:

        • 你有上面的 swift 版本吗?或者如果可能的话,你能重新写一下吗?
        • 你介意分享你用来加载你正在渲染的 webView 的代码吗?对于我的缩略图渲染器来说,这似乎是一种很有前途的方法。谢谢!
        【解决方案17】:

        我不认为这是最好的答案,但发帖似乎很有趣。

        编写一个应用程序,将您最喜欢的浏览器打开到所需的 HTML 文档、适当调整窗口大小并截屏。然后,移除图像的边框。

        【讨论】:

        • 与无头 Chrome 屏幕截图解决方案相同,但对全球变暖的贡献很大。
        • 如果9 年前只有当前选项可用...
        • 如果一个答案在 9 年后基本正确且相关,以至于您省略了日期 (:
        【解决方案18】:

        您可以使用 wkhtmltopdf 等 HTML 转 PDF 工具。然后你可以使用像 imagemagick 这样的 PDF 图像工具。诚然,这是服务器端和一个非常复杂的过程......

        【讨论】:

        • 或者你可以直接运行 wkhtmltopdf 的镜像兄弟 wkhtmltoimage。
        • 这个库是给Node.js的。简单的前端怎么样?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-16
        • 1970-01-01
        • 2014-07-30
        • 2015-03-15
        相关资源
        最近更新 更多