Есть ли способ визуализации html для изображения, такого как PNG? Я знаю, что это возможно с холстом, но я бы хотел отобразить стандартный элемент html, например div.
Отобразить HTML-изображение
Ответ 1
Я знаю, что это довольно старый вопрос, на который уже есть много ответов, но я все еще часами пытался сделать то, что хотел:
- учитывая 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-адрес...)
Ответ 2
Да. HTML2Canvas существует для рендеринга HTML на <canvas>
(который затем можно использовать в качестве изображения).
ПРИМЕЧАНИЕ. Известна проблема, что это не будет работать с SVG
Ответ 3
Могу ли я рекомендовать библиотеку 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);
});
Ответ 4
Вариантов много, и у всех есть свои плюсы и минусы.
Вариант 1. Используйте одну из многих доступных библиотек.
- дом-к-изображения
- wkhtmltoimage (включен в инструмент wkhtmltopdf)
- IMGKit (для ruby и на основе wkhtmltoimage)
- imgkit (для Python и на основе wkhtmltoimage)
- питон-webkit2png
- ...
Pros
- Конверсия в большинстве случаев довольно быстрая
Cons
- Плохой рендеринг
- Не выполняет JavaScript
- Отсутствует поддержка последних веб-функций (FlexBox, Расширенные селекторы, Веб-шрифты, Размеры ящиков, Медиа-запросы,...)
- Иногда не так просто установить
- Сложно масштабировать
Вариант 2: используйте PhantomJs и, возможно, библиотеку-обертку
- PhantomJs
- node-webshot (библиотека-обертка для JavaScript для PhantomJs)
- ...
Pros
- Выполнить Javascript
- Довольно быстро
Cons
- Плохой рендеринг
- Отсутствует поддержка последних веб-функций (FlexBox, Расширенные селекторы, Веб-шрифты, Размеры ящиков, Медиа-запросы,...)
- Сложно масштабировать
- Не так легко заставить его работать, если есть загружаемые изображения...
Вариант 3: используйте Chrome Headless и, возможно, библиотеку-обертку
- Chrome Headless
- хром-DevTools-протокол
- Puppeteer (библиотека-обёртка для JavaScript без головы)
- ...
Pros
- Выполнить Javascript
- Почти идеальный рендеринг
Cons
- Не так просто получить желаемый результат в отношении:
- время загрузки страницы
- размеры окна просмотра
- Сложно масштабировать
- Довольно медленно и даже медленнее, если HTML содержит внешние ссылки
Вариант 4: использовать API
- ApiFlash (на основе хрома)
- EvoPDF (имеет опцию для HTML)
- Grabzit
- API HTML/CSS для изображений
- ...
Pros
- Выполнить Javascript
- Почти идеальный рендеринг
- Быстро при правильном использовании параметров кэширования
- Шкала обрабатывается API
- Точное время, окно просмотра,...
- Большую часть времени они предлагают бесплатный план
Cons
- Не бесплатно, если вы планируете использовать их много
Отказ от ответственности: я основатель ApiFlash. Я сделал все возможное, чтобы дать честный и полезный ответ.
Ответ 5
Все ответы здесь используют сторонние библиотеки, в то время как рендеринг HTML в изображение может быть относительно простым в чистом Javascript. Там будет даже статья об этом в разделе холст на MDN.
Хитрость заключается в следующем:
- создать SVG с узлом foreignObject, содержащим ваш XHTML
- установить источник изображения в URL-адрес данных SVG
-
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()
}
Ответ 6
Вы можете использовать PhantomJS, который представляет собой безгласный веб-кит (механизм рендеринга в сафари и (до недавнего времени) хром) драйвер, Вы можете узнать, как делать снимки экрана страниц здесь. Надеюсь, что это поможет!
Ответ 7
Вы можете использовать инструмент HTML для PDF, например wkhtmltopdf. И тогда вы можете использовать PDF-инструмент для создания изображений, например, imagemagick. По общему признанию, это серверная сторона и очень запутанный процесс...
Ответ 8
Единственная библиотека, которую я получил для работы с 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);
}
});
Ответ 9
Я не ожидаю, что это будет лучшим ответом, но он казался достаточно интересным для публикации.
Напишите приложение, которое откроет ваш любимый браузер в нужном HTML-документе, правильно закроет окно и сделает снимок экрана. Затем удалите границы изображения.
Ответ 10
Вы не можете сделать это на 100% точно с помощью JavaScript.
Здесь есть инструмент Qt Webkit и версия python. Если вы хотите сделать это самостоятельно, у меня был успех с 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];
}];
Надеюсь, это поможет!
Ответ 11
Используйте 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/
Ответ 12
Используйте этот код, он обязательно будет работать:
<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>
Ответ 13
Установить 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
Ответ 14
Вы, конечно, можете. GrabzIt JavaScript API позволяет вам захватывать div с веб-страницы следующим образом:
<script type="text/javascript" src="grabzit.min.js"></script>
<script type="text/javascript">
GrabzIt("Your Application Key").ConvertURL("http://www.example.com/my-page.html",
{"target": "#features", "bheight": -1, "height": -1, "width": -1}).Create();
</script>
Где #features - идентификатор div для захвата. Если вы хотите конвертировать HTML в изображение. Вы можете использовать эту технику:
GrabzIt("Your Application Key").ConvertHTML(
"<html><body><h1>Hello World!</h1></body></html>").Create();
Отказ от ответственности Я построил этот API!
Ответ 15
Рисование объектов DOM в холст показывает быстрый способ выполнить это.
С точки зрения производительности этот метод должен быть легким. Поскольку рендеринг svg и рендеринга dom могут, по-видимому, передавать буферы туда и обратно по мере необходимости. Это имеет смысл, потому что это весь основной код.
У меня нет никаких эталонных показателей, но документы MDN довольно хорошо поддерживаются и не только для gecko. Поэтому я предполагаю, что вы, по крайней мере, можете знать, что плохая производительность - это проблема, которая будет рассмотрена в какой-то момент.
Ответ 16
HtmlToImage.jar будет самым простым способом конвертировать HTML в изображение
Ответ 17
Вы можете добавить ссылку HtmlRenderer в свой проект и сделать следующее:
string htmlCode ="<p>This is a sample html.</p>";
Image image = HtmlRender.RenderToImage(htmlCode ,new Size(500,300));