Вопрос по javascript, html, render, css, image – Рендеринг HTML в изображение

112

Есть ли способ визуализации HTML для изображения, как PNG? Я знаю, что это возможно с холстом, но я хотел бы сделать стандартный элемент HTML, например, div.

Я хочу использовать HTML / CSS для разработки логотипа. Martin Delille
возможный дубликатHow to convert HTML of a website to an image? Ernest Friedman-Hill
@ ErnestFriedman-Hill не дубликат: вопрос, который вы упомянули, относится к java. Martin Delille
Вот пошаговое руководство по преобразованию HTML в формат IMAGE png или jpegcodepedia.info/2016/02/… Satinder singh
Чтобы создать какую-то помощь пользователю, например. К сожалению, это невозможно (по соображениям безопасности?). Вы должны попросить пользователя нажать PrintScreen, чтобы что-то сделать. MaxArt

Ваш Ответ

15   ответов
2

Там есть Qt Webkitинструмент из там иверсия на питоне, Если вы хотите сделать это самостоятельно, у меня был успех с Какао:

[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];
}];

Надеюсь это поможет!

У вас есть быстрая версия выше? или, если возможно, вы можете переписать это?
Не могли бы вы поделиться кодом, который вы используете для загрузки веб-представления, которое вы отображаете? Это выглядит многообещающим подходом для моего рендера. Спасибо!
8

с которой я работал на Chrome, Firefox и MS Edge, былаrasterizeHTML, Он выводит лучшее качество, чем HTML2Canvas, и поддерживается в отличие от HTML2Canvas.

Getting Element and Downloading as 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);
            }
     });
Этот ответ должен быть на вершине! Лучший инструмент на данный момент.
но он не работает с IE.rasterizeHTML Limitations
@ Vabanagas есть ли какой-нибудь отдельный файл JavaScript для этого?
69

дом-к-изображения библиотека, которая была написана исключительно для решения этой проблемы (я сопровождающий).
Вот как вы используете его (еще немногоВот):

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);
    });
@ Subho это строка, содержащая URL с данными в кодировке base64
Это замечательно! Любой способ удвоить выходной размер?
Спасибо! Но что именно вы подразумеваете под «удвоением размера»?
Это НАМНОГО лучше, чем html2canvas. Благодарю.
Первое, что приходит мне в голову - попробуйте отрисовать ваше изображение в SVG (используяdomtoimage.toSvg), затем визуализируйте его самостоятельно на холсте и попробуйте поиграть с этим холстом & apos; разрешение как-то. Вероятно, возможно реализовать такую функцию, как какой-то вариант рендеринга в самой библиотеке, чтобы можно было передавать размеры изображения в пикселях. Если вам это нужно, я буду благодарен вам за то, что вы создали проблему на github.
1

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();
        });

Source: http://www.freakyjolly.com/convert-html-document-into-image-jpg-png-from-canvas/

5

что это будет лучшим ответом, но публикация показалась мне достаточно интересной.

Напишите приложение, которое открывает ваш любимый браузер для нужного HTML-документа, правильно устанавливает размеры окна и делает снимок экрана. Затем удалите границы изображения.

AKX опубликовал интересный ответ, но мне не удалось заставить его работать ... Martin Delille
1

Установить фантоми

$ 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
-3

add reference HtmlRenderer к вашему проекту и сделайте следующее,

string htmlCode ="<p>This is a sample html.</p>";
Image image = HtmlRender.RenderToImage(htmlCode ,new Size(500,300));
это хорошо, но это не связано с темой
0

<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>

Только не забудьте включить файл Html2CanvasJS в вашу программу. https://html2canvas.hertzen.com/dist/html2canvas.js

13

PhantomJS, который представляет собой безголовый webkit (движок рендеринга в safari и (до недавнего времени) chrome) драйвер. Вы можете узнать, как сделать снимок экрана страницВот, Надеюсь, это поможет!

Безголовый Chrome теперь возможен. Я не знаю, быстрее ли это, но если вам нужны точные скриншоты, это хороший способ.
Эта техника хорошо работает. Однако с момента вашего комментария прошло 2 года. Сталкивались ли вы с чем-нибудь, что работает быстрее, чем PhantomJS? Генерация изображения в Phantom обычно занимает 2-5 секунд.
36

Option 1: Use one of the many available libraries dom-to-image wkhtmltoimage (included in the wkhtmltopdf tool) IMGKit (for ruby and based on wkhtmltoimage) imgkit (for python and based on wkhtmltoimage) python-webkit2png ...

Pros

Conversion is quite fast most of the time

Cons

Bad rendering Does not execute javascript No support for recent web features (FlexBox, Advanced Selectors, Webfonts, Box Sizing, Media Queries, ...) Sometimes not so easy to install Complicated to scale Option 2: Use PhantomJs and maybe a wrapper library PhantomJs node-webshot (javascript wrapper library for PhantomJs) ...

Pros

Execute Javascript Quite fast

Cons

Bad rendering No support for recent web features (FlexBox, Advanced Selectors, Webfonts, Box Sizing, Media Queries, ...) Complicated to scale Not so easy to make it work if there is images to be loaded ... Option 3: Use Chrome Headless and maybe a wrapper library Chrome Headless chrome-devtools-protocol Puppeteer (javascript wrapper library for Chrome headless) ...

Pros

Execute Javascript Near perfect rendering

Cons

Not so easy to have exactly the wanted result regarding: page load timing viewport dimensions Complicated to scale Quite slow and even slower if the html contains external links Option 4: Use an API ApiFlash (based on chrome) EvoPDF (has an option for html) Grabzit HTML/CSS to Image API ...

Pros

Execute Javascript Near perfect rendering Fast when caching options are correctly used Scale is handled by the APIs Precise timing, viewport, ... Most of the time they offer a free plan

Cons

Not free if you plan to use them a lot

Disclaimer: I'm the founder of ApiFlash. I did my best to provide an honest and useful answer.

Спасибо за подробный ответ с множеством возможных решений
wkhtmltoimage / pdf поддерживает рендеринг JavaScript. Вы можете установить задержку javascript или позволить wkhtml проверять конкретный window.status (который можно установить с помощью javascript, когда вы знаете, что ваши js-файлы выполнены)
1

JavaScript API GrabzIt позволяет вам захватить 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();

Disclaimer I built this API!

0

Рисование DOM-объектов на холсте показывает быстрый способ сделать это.

С точки зрения производительности этот метод должен быть легким. Поскольку рендерер svg и рендер dom, по-видимому, могут передавать буферы обратно & amp; вперед по мере необходимости. Это имеет смысл, потому что это весь основной код.

У меня нет никаких критериев этого, но документы MDN довольно хорошо поддерживаются и не только для геккона. Поэтому я предполагаю, что вы, по крайней мере, знаете, что плохая производительность - это проблема, которая будет решена в какой-то момент.

20

в то время как рендеринг HTML в изображение может быть относительно простым в чистом Javascript. Тамis был дажестатья об этом на холсте раздел на мдн.

Хитрость заключается в следующем:

create an SVG with a foreignObject node containing your XHTML set the src of an image to the data url of that SVG drawImage onto the canvas set canvas data to target 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()
}

Некоторые вещи на заметку

The HTML inside the SVG has to be XHTML For security reasons the SVG as data url of an image acts as an isolated CSS scope for the HTML since no external sources can be loaded. So a Google font for instance has to be inlined using a tool like this one. Even when the HTML inside the SVG exceeds the size of the image it wil draw onto the canvas correctly. But the actual height cannot be measured from that image. A fixed height solution will work just fine but dynamic height will require a bit more work. The best is to render the SVG data into an iframe (for isolated CSS scope) and use the resulting size for the canvas.
Ницца! Удаление зависимости от внешних библиотек - действительно хороший путь. Я изменил свой принятый ответ :-) Martin Delille
Этой статьи больше нет.
Этот ответstackoverflow.com/questions/12637395/… кажется, указывает, что вы можете пойти довольно далеко. Mozilla и Chrome имеют неограниченное количество данных, и даже текущий IE позволяет использовать 4 ГБ, что сводится к примерно 3 ГБ изображениям (благодаря base64). Но это было бы хорошо, чтобы проверить.
- некоторые быстрые и грязные тесты позже -jsfiddle.net/Sjeiti/pcwudrmc/75965 Размеры Chrome, Edge и Firefox достигают ширины ширины не менее 10 000 пикселей, что (в данном случае) составляет около 10 000 000 символов и размер файла png составляет 8 МБ. Испытания не проводились строго, но этого достаточно для большинства случаев использования.
Отличный ответ, но комментируя современное состояние HTML и веб-API, которые, как обычно, выглядят как что-то, что вытянуло кого-то позади - технически все функции присутствуют, но раскрыты за массивом (без каламбура) странных путей кода, которые напоминают ничего такого, чего бы вы не ожидали от хорошо спроектированных API. Проще говоря: браузер, скорее всего, тривиально разрешитьDocument быть преобразованным в растр (например,Canvas), но поскольку никто не удосужился стандартизировать его, мы должны прибегнуть к безумию, как показано выше (без обид на автора этого кода).
90

HTML2Canvas существует для рендеринга HTML на<canvas> (который вы можете использовать в качестве изображения).

ПРИМЕЧАНИЕ: есть известная проблема, что это не будет работать с SVG

@MartinDelille: здесь статья об использовании HTML2Canvas для создания IMAGE, и вы также можете скачать его на стороне клиентаcodepedia.info/2016/02/…
Дом-к-изображению (см. ответ Цайена) делает намного лучшую работу для получения точного изображения.
Это решение очень медленное
Это кажется интересным, но мне не удалось заставить его работать, поэтому я выбрал решение Джона Фишера. Спасибо за информацию, я буду смотреть этот проект в будущем! Martin Delille
другая проблема, если элемент скрыт или находится за другим элементом, это не будет работать
11

например wkhtmltopdf. И тогда вы можете использовать PDF для изображения инструмента, как imagemagick. По общему признанию это - сторона сервера и очень запутанный процесс ...

Эта библиотека дляNode.js, Как насчет простого интерфейса?
@romkyns +1, я никогда этого не знал!
Или вы можете просто запустить изображение брата wkhtmltopdf, wkhtmltoimage.

Похожие вопросы