是否有一种方法将html渲染成PNG那样的图像?我知道这是可能的与画布,但我想渲染标准的html元素,如div为例。
当前回答
这就是我所做的。
注意:请检查App.js的代码。
链接到源代码
如果你喜欢它,你可以掉一颗星。✌️
更新:
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;
其他回答
我读了Sjeiti的答案,我觉得很有趣,在那里你只需要几行简单的JavaScript就可以在图像中呈现HTML。
当然,我们必须意识到这种方法的局限性(请在他的回答中阅读其中的一些)。
在这里,我进一步使用了他的代码。
svg图像原则上具有无限分辨率,因为它是矢量图形。但您可能已经注意到,Sjeiti的代码生成的图像分辨率并不高。在将SVG-image转移到canvas-element之前,可以通过缩放SVG-image来解决这个问题,我在下面给出的两个(可运行的)示例代码中的最后一个代码中已经做到了这一点。我在该代码中实现的另一件事是最后一步,即将其保存为png文件。只是为了完成整个过程。
因此,我给出了两个可运行的代码片段:
第一个演示了SVG的无限分辨率。运行它并使用浏览器放大,以查看分辨率是否随着放大而减小。
在您可以运行的代码片段中,我已经使用反勾号指定了一个带有换行符的所谓模板字符串,以便您可以更清楚地看到呈现的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);
这里是一个可运行的代码片段。
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> 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> 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();" /> 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 <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。
因此,我也把这个片段放在https://jsfiddle.net/7gozdq5v/上,它适用于这些浏览器。
请允许我推荐dom-to-image库,这是专门用来解决这个问题的(我是维护者)。 下面是你如何使用它(更多):
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);
});
仅用JavaScript无法100%准确地做到这一点。
有一个Qt Webkit工具,还有一个python版本。如果你想自己做,我已经成功地用可可:
[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];
}];
希望这能有所帮助!
我推荐这个npm包“html-to-image”
描述: ✂️使用HTML5画布和SVG从DOM节点生成图像。
使用方法:
安装
npm install --save html-to-image
使用
/* ES6 */
import * as htmlToImage from 'html-to-image';
import { toPng, toJpeg, toBlob, toPixelData, toSvg } from 'html-to-image';
获取一个PNG图像base64编码的数据URL并下载它(使用download):
htmlToImage.toPng(document.getElementById('my-node'))
.then(function (dataUrl) {
download(dataUrl, 'my-node.png');
});
使用这段代码,它一定会工作:
<脚本type = " text / javascript”> 美元(文档)。Ready (function () { setTimeout(函数(){ downloadImage (); }, 1000) }); 函数downloadImage () { html2canvas (document.querySelector(“# dvContainer”))。然后(canvas => { a = document.createElement('a'); document.body.appendChild(一个); A.download = "test.png"; a.href = canvas.toDataURL(); a.click (); }); } > < /脚本
不要忘记在你的程序中包含Html2CanvasJS文件。 https://html2canvas.hertzen.com/dist/html2canvas.js
推荐文章
- 给一个数字加上st, nd, rd和th(序数)后缀
- 如何以编程方式触发引导模式?
- setTimeout带引号和不带括号的区别
- 为什么我的CSS3媒体查询不能在移动设备上工作?
- 在JS的Chrome CPU配置文件中,'self'和'total'之间的差异
- 用javascript检查输入字符串中是否包含数字
- 如何使用JavaScript分割逗号分隔字符串?
- 在Javascript中~~(“双波浪号”)做什么?
- 谷歌chrome扩展::console.log()从后台页面?
- 下一个元素的CSS选择器语法是什么?
- 未捕获的SyntaxError:
- 是否有'box-shadow-color'属性?
- [].slice的解释。调用javascript?
- 在jQuery中的CSS类更改上触发事件
- jQuery日期/时间选择器