是否有一种方法将html渲染成PNG那样的图像?我知道这是可能的与画布,但我想渲染标准的html元素,如div为例。
当前回答
我在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);
}
});
其他回答
仅用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];
}];
希望这能有所帮助!
有很多选择,它们都有各自的优点和缺点。
选项1:使用API
ApiFlash(基于chrome) EvoPDF(有html选项) Grabzit HTML/CSS图像API ...
Pros
执行Javascript 近乎完美渲染 正确使用缓存选项时快速 缩放由api处理 精确计时,视口,… 大多数时候,他们提供的是免费方案
Cons
如果你打算经常使用它们,就不是免费的
选项2:使用众多可用库中的一个
dom-to-image Wkhtmltoimage(包含在wkhtmltopdf工具中) IMGKit(用于ruby和基于wkhtmltoimage) Imgkit(适用于python,基于wkhtmltoimage) python-webkit2png ...
Pros
大多数时候,转换是相当快的
Cons
坏的呈现 不执行javascript 不支持最近的网页功能(FlexBox,高级选择器,网页字体,盒子大小,媒体查询,…) 有时不容易安装 缩放复杂
选项3:使用PhantomJs和包装器库
PhantomJs node-webshot(用于PhantomJs的javascript包装库) ...
Pros
执行Javascript 很快
Cons
坏的呈现 不支持最近的网页功能(FlexBox,高级选择器,网页字体,盒子大小,媒体查询,…) 缩放复杂 不那么容易使它工作,如果有图像要加载…
选项4:使用Chrome Headless和一个包装器库
Chrome无头 chrome-devtools-protocol Puppeteer (Chrome无头浏览器的javascript包装库) ...
Pros
执行Javascript 近乎完美渲染
Cons
要得到想要的结果并不容易: 页面加载时间 视窗尺寸 缩放复杂 相当慢,甚至更慢,如果html包含外部链接
披露:我是ApiFlash的创始人。我尽力提供了一个诚实而有用的答案。
我知道这是一个已经有很多答案的老问题,但我仍然花了很多时间去做我想做的事情:
给定一个HTML文件,从命令行生成一个带有透明背景的(png)图像
使用Chrome headless (version 74.0.3729.157),实际上很容易:
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --headless --screenshot --window-size=256,256 --default-background-color=0 button.html
命令使用说明:
you run Chrome from the command line (here shown for the Mac, but assuming similar on Windows or Linux) --headless runs Chrome without opening it and exits after the command completes --screenshot will capture a screenshot (note that it generates a file called screenshot.png in the folder where the command is run) --window-size allow to only capture a portion of the screen (format is --window-size=width,height) --default-background-color=0 is the magic trick that tells Chrome to use a transparent background, not the default white color finally you provide the html file (as a url either local or remote...)
这就是我所做的。
注意:请检查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;
使用这段代码,它一定会工作:
<脚本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