Czy istnieje sposób na renderowanie HTML do obrazu, takiego jak PNG? Wiem, że jest to możliwe z płótnem, ale chciałbym renderować standardowy element html, na przykład div.
Czy istnieje sposób na renderowanie HTML do obrazu, takiego jak PNG? Wiem, że jest to możliwe z płótnem, ale chciałbym renderować standardowy element html, na przykład div.
Odpowiedzi:
Wiem, że to dość stare pytanie, które ma już wiele odpowiedzi, a mimo to godzinami próbowałem robić to, co chciałem:
Korzystając z Chrome headless (wersja 74.0.3729.157 z tej odpowiedzi), jest to w rzeczywistości łatwe:
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --headless --screenshot --window-size=256,256 --default-background-color=0 button.html
Wyjaśnienie polecenia:
--headless
uruchamia Chrome bez otwierania go i zamyka po wykonaniu polecenia--screenshot
przechwyci zrzut ekranu (pamiętaj, że generuje plik o nazwie screenshot.png
w folderze, w którym polecenie jest uruchamiane)--window-size
pozwalają uchwycić tylko część ekranu (format jest --window-size=width,height
)--default-background-color=0
to magiczna sztuczka, która mówi Chrome, że ma używać przezroczystego tła, a nie domyślnego białego koloru--screenshot='absolute\path\of\screenshot.png'
pracował dla mnie
Tak. HTML2Canvas istnieje do renderowania kodu HTML <canvas>
(którego można następnie użyć jako obrazu).
UWAGA: istnieje znany problem, że to nie zadziała z SVG
Mogę polecić bibliotekę dom-to-image , która została napisana wyłącznie w celu rozwiązania tego problemu (jestem opiekunem).
Oto jak go używasz (więcej tutaj ):
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);
});
domtoimage.toSvg
), a następnie wyrenderuj go samodzielnie na płótnie i spróbuj jakoś pobawić się rozdzielczością tego płótna. Prawdopodobnie możliwe jest zaimplementowanie takiej funkcji, jak pewna opcja renderowania w samej bibliotece, dzięki czemu można przekazywać wymiary obrazu w pikselach. Jeśli tego potrzebujesz, byłbym wdzięczny za utworzenie numeru na github.
Opcji jest wiele i wszystkie mają swoje wady i zalety.
Plusy
Cons
Plusy
Cons
Plusy
Cons
Plusy
Cons
Ujawnienie: jestem założycielem ApiFlash. Zrobiłem co w mojej mocy, aby udzielić uczciwej i użytecznej odpowiedzi.
Wszystkie odpowiedzi tutaj wykorzystują biblioteki stron trzecich, podczas gdy renderowanie HTML do obrazu może być stosunkowo proste w czystym JavaScript. Nie jest nawet artykuł o tym na odcinku płótno na MDN.
Sztuczka jest taka:
drawImage
na płótnieconst {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()
}
Kilka rzeczy do zapamiętania
Document
na renderowanie a do rastra (np. A Canvas
), ale ponieważ nikt nie zadał sobie trudu, aby go ujednolicić, musimy uciekać się do szaleństwa, jak pokazano powyżej (bez urazy dla autora tego kod).
Możesz użyć PhantomJS , który jest bezgłowym webkitem (silnik renderujący w Safari i (do niedawna) chrome). Można dowiedzieć się, jak zrobić zrzut ekranu stron tutaj . Mam nadzieję, że to pomoże!
Możesz użyć narzędzia HTML do PDF, takiego jak wkhtmltopdf. Następnie możesz użyć narzędzia PDF do obrazowania, takiego jak imagemagick. Trzeba przyznać, że jest to strona serwera i bardzo zawiły proces ...
Node.js
. A co z prostym interfejsem użytkownika?
Jedyną biblioteką, którą udało mi się pracować dla Chrome, Firefox i MS Edge, była rasterizeHTML . Zapewnia lepszą jakość niż HTML2Canvas i nadal jest obsługiwany w przeciwieństwie do HTML2Canvas.
Pobieranie elementu i pobieranie jako 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);
}
});
rasterizeHTML.drawHTML(node.innerHTML, canvas)
Zwróć uwagę, że dzwonię do innerHTML na węźle
Użyj html2canvas, po prostu dołącz wtyczkę i wywołaj metodę, aby przekonwertować HTML na Canvas, a następnie pobrać jako obraz 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();
});
Źródło : http://www.freakyjolly.com/convert-html-document-into-image-jpg-png-from-canvas/
Nie spodziewam się, że to będzie najlepsza odpowiedź, ale opublikowanie tego wydawało się wystarczająco interesujące.
Napisz aplikację, która otwiera Twoją ulubioną przeglądarkę na żądany dokument HTML, odpowiednio dopasowuje rozmiar okna i wykonuje zrzut ekranu. Następnie usuń krawędzie obrazu.
Użyj tego kodu, na pewno zadziała:
<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>
Nie zapomnij tylko o dołączeniu pliku Html2CanvasJS do swojego programu. https://html2canvas.hertzen.com/dist/html2canvas.js
Nie możesz tego zrobić w 100% dokładnie za pomocą samego JavaScript.
Jest tam narzędzie Qt Webkit i wersja dla Pythona . Jeśli chcesz to zrobić sam, odniosłem sukces z 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];
}];
Mam nadzieję że to pomoże!
Zainstaluj phantomjs
$ npm install phantomjs
Utwórz plik github.js z następującym kodem
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();
});
Przekaż plik jako argument do phantomjs
$ phantomjs github.js
HtmlToImage.jar będzie najprostszym sposobem konwersji html na obraz
Możesz dodać referencyjny HtmlRenderer do swojego projektu i wykonać następujące czynności,
string htmlCode ="<p>This is a sample html.</p>";
Image image = HtmlRender.RenderToImage(htmlCode ,new Size(500,300));