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.
Na przykład, aby utworzyć rodzaj pomocy dla użytkownika. Niestety nie jest to możliwe (ze względów bezpieczeństwa?). Musisz poprosić użytkownika o naciśnięcie PrintScreen, aby coś zrobić.
Wydaje się to interesujące, ale nie udało mi się tego zrobić, więc wybrałem rozwiązanie Johna Fishera. Dzięki za informację, będę oglądać ten projekt w przyszłości!
Martin Delille
@MartinDelille: tutaj artykuł o używaniu HTML2Canvas do tworzenia OBRAZÓW, który można również pobrać ze strony klienta codepedia.info/2016/02/…
Satinder singh
3
dom-to-image (patrz odpowiedź tsayen) znacznie lepiej radzi sobie z renderowaniem dokładnego obrazu.
JBE
3
To rozwiązanie jest bardzo powolne
hamboy75
3
kolejna kwestia, jeśli element jest ukryty lub za innym elementem, to nie zadziała
Yousef
91
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 =newImage();
img.src = dataUrl;
document.appendChild(img);}).catch(function(error){
console.error('oops, something went wrong!', error);});
To jest świetne! Jakiś sposób na podwojenie rozmiaru wyjściowego?
cronoklee
Dzięki! Ale co dokładnie masz na myśli mówiąc „podwojenie rozmiaru”?
tsayen
2
Pierwsza rzecz, która przychodzi mi do głowy - spróbuj wyrenderować obraz do SVG (używając 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.
tsayen
8
To DUŻO lepsze niż html2canvas. Dzięki.
c.hughes,
1
@Subho to ciąg znaków zawierający adres URL z danymi zakodowanymi w base64
tsayen
66
Opcji jest wiele i wszystkie mają swoje wady i zalety.
Dziękuję za szczegółową odpowiedź z wieloma możliwymi rozwiązaniami
bszom
wkhtmltoimage / pdf obsługuje renderowanie javascript. Możesz ustawić opóźnienie javascript lub pozwolić wkhtml sprawdzić, czy istnieje konkretny window.status (który możesz ustawić za pomocą javascript, gdy wiesz, że wszystko jest gotowe)
Daniel
PhantomJS obsługuje dynamiczne rzeczy, takie jak Mapy Google. To naprawdę pełna przeglądarka internetowa, tylko bez podłączonego wyświetlacza. Jednak trzeba trochę poczekać, aż Google Map załaduje kafelki z geografią (czekam 500ms i pozwalam ludziom zmienić opóźnienie - jeśli to nie wystarczy, ponowne uruchomienie bez zwiększania czasu jest w porządku, ponieważ te kafelki są buforowane).
Ladislav Zima
50
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:
utwórz SVG z węzłem ForeignObject zawierającym Twój XHTML
ustaw źródło obrazu na adres URL danych tego pliku SVG
Ze względów bezpieczeństwa plik SVG jako adres URL obrazu działa jako izolowany zakres CSS dla HTML, ponieważ nie można załadować żadnych zewnętrznych źródeł. Na przykład czcionka Google musi być wbudowana za pomocą narzędzia takiego jak to .
Nawet jeśli kod HTML wewnątrz SVG przekracza rozmiar obrazu, zostanie poprawnie narysowany na płótnie. Ale rzeczywistej wysokości nie można zmierzyć na podstawie tego obrazu. Rozwiązanie o stałej wysokości będzie działać dobrze, ale dynamiczna wysokość będzie wymagać nieco więcej pracy. Najlepiej jest wyrenderować dane SVG w ramce iframe (dla izolowanego zakresu CSS) i użyć wynikowego rozmiaru dla płótna.
Miły! Usunięcie zależności od zewnętrznych bibliotek jest rzeczywiście dobrym rozwiązaniem. Zmieniłem zaakceptowaną odpowiedź :-)
Martin Delille
Tego artykułu już nie ma.
MSC
2
Świetna odpowiedź, ale komentując stan techniki HTML i interfejsów API sieci Web, które jak zwykle wygląda jak coś wyciągniętego za kogoś - cała funkcjonalność jest tam technicznie, ale jest ujawniona za tablicą (gra słów nie zamierzona) dziwnych ścieżek kodu, które przypominają nic takiego, jakiego można by się spodziewać po dobrze zaprojektowanych interfejsach API. Mówiąc prościej: to jest najprawdopodobniej trywialne dla przeglądarki, aby pozwolić Documentna 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).
amn
1
Ta odpowiedź stackoverflow.com/questions/12637395/… wydaje się wskazywać, że można zajść całkiem daleko. Mozilla i Chrome mają nieograniczoną długość danych, a nawet obecny IE pozwala na 4 GB, co sprowadza się do około 3 GB obrazów (ze względu na base64). Ale dobrze byłoby to przetestować.
Sjeiti
3
- kilka szybkich i brudnych testów później - jsfiddle.net/Sjeiti/pcwudrmc/75965 Chrome, Edge i Firefox osiągają szerokość co najmniej 10000 pikseli, co (w tym przypadku) jest liczbą znaków około 10000000 i rozmiar pliku png 8 MB. Nie był testowany rygorystycznie, ale wystarcza w większości przypadków użycia.
Sjeiti
13
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!
Ta technika działa dobrze. Jednak od twojego komentarza minęły 2 lata. Czy spotkałeś coś, co działa szybciej niż PhantomJS? Z mojego doświadczenia wynika, że generowanie obrazu w Phantomie zajmuje zazwyczaj 2-5 sekund.
Brian Webster
Headless Chrome jest teraz możliwy. Nie wiem, czy jest szybsze, ale jeśli chcesz dokładnych zrzutów ekranu, to jest dobry sposób.
Josh Maag
11
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 ...
Możesz też po prostu uruchomić obraz brat wkhtmltopdf, wkhtmltoimage.
Roman Starkov
1
Ta biblioteka jest przeznaczona dla Node.js. A co z prostym interfejsem użytkownika?
Vlad
9
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.
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.
Czy masz szybką wersję powyższego? lub jeśli to możliwe, czy możesz napisać go ponownie?
ssh
Czy mógłbyś udostępnić kod, którego używasz do ładowania webView, który renderujesz? Wydaje się, że to obiecujące podejście do mojego modułu renderowania miniatur. Dzięki!
Dave,
1
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();});
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:
Wyjaśnienie polecenia:
--headless
uruchamia Chrome bez otwierania go i zamyka po wykonaniu polecenia--screenshot
przechwyci zrzut ekranu (pamiętaj, że generuje plik o nazwiescreenshot.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źródło
--screenshot='absolute\path\of\screenshot.png'
pracował dla mnieTak. 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
źródło
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 ):
źródło
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.
Opcja 1: użyj jednej z wielu dostępnych bibliotek
Plusy
Cons
Opcja 2: Użyj PhantomJs i być może biblioteki opakowującej
Plusy
Cons
Opcja 3: użyj Chrome Headless i być może biblioteki otoki
Plusy
Cons
Opcja 4: użyj interfejsu API
Plusy
Cons
Ujawnienie: jestem założycielem ApiFlash. Zrobiłem co w mojej mocy, aby udzielić uczciwej i użytecznej odpowiedzi.
źródło
Wszystkie odpowiedzi tutaj wykorzystują biblioteki stron trzecich, podczas gdy renderowanie HTML do obrazu może być stosunkowo proste w czystym JavaScript. Nie
jestnawet artykuł o tym na odcinku płótno na MDN.Sztuczka jest taka:
drawImage
na płótnieKilka rzeczy do zapamiętania
źródło
Document
na renderowanie a do rastra (np. ACanvas
), 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!
źródło
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 ...
źródło
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
źródło
rasterizeHTML.drawHTML(node.innerHTML, canvas)
Zwróć uwagę, że dzwonię do innerHTML na węźleUżyj html2canvas, po prostu dołącz wtyczkę i wywołaj metodę, aby przekonwertować HTML na Canvas, a następnie pobrać jako obraz PNG
Źródło : http://www.freakyjolly.com/convert-html-document-into-image-jpg-png-from-canvas/
źródło
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.
źródło
Użyj tego kodu, na pewno zadziała:
Nie zapomnij tylko o dołączeniu pliku Html2CanvasJS do swojego programu. https://html2canvas.hertzen.com/dist/html2canvas.js
źródło
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:
Mam nadzieję że to pomoże!
źródło
Zainstaluj phantomjs
Utwórz plik github.js z następującym kodem
Przekaż plik jako argument do phantomjs
źródło
HtmlToImage.jar będzie najprostszym sposobem konwersji html na obraz
Konwersja HTML do obrazu przy użyciu java
źródło
Możesz dodać referencyjny HtmlRenderer do swojego projektu i wykonać następujące czynności,
źródło