IT story

HTML을 이미지로 렌더링

hot-time 2020. 6. 24. 07:30
반응형

HTML을 이미지로 렌더링


PNG와 같이 HTML을 이미지로 렌더링하는 방법이 있습니까? 캔버스에서 가능하다는 것을 알고 있지만 예를 들어 div와 같은 표준 HTML 요소를 렌더링하고 싶습니다.


나는 이것이 이미 많은 답변을 가지고있는 아주 오래된 질문이라는 것을 알고 있지만 실제로 내가 원하는 것을 실제로하려고 노력하는 데 몇 시간을 보냈습니다.

  • 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=0Chrome에 기본 흰색이 아닌 투명한 배경 을 사용하도록 지시하는 마술
  • 마지막으로 html 파일을 제공하십시오 (로컬 또는 원격 URL로).

예. HTML2Canvas 는 HTML을 렌더링하기 위해 존재합니다 <canvas>(이미지로 사용할 수 있음).

참고 : SVG에서 작동하지 않는 알려진 문제가 있습니다.


이 문제를 해결하기 위해 작성된 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);
    });

많은 옵션이 있으며 모두 장단점이 있습니다.

옵션 1 : 사용 가능한 많은 라이브러리 중 하나 사용

찬성

  • 대부분의 경우 변환은 매우 빠릅니다.

단점

  • 잘못된 렌더링
  • 자바 스크립트를 실행하지 않습니다
  • 최근 웹 기능 (FlexBox, 고급 선택기, 웹 폰트, 상자 크기 조정, 미디어 쿼리 등)은 지원하지 않습니다.
  • 때로는 설치가 쉽지 않은 경우가 있습니다
  • 규모가 복잡하다

옵션 2 : PhantomJ 및 랩퍼 라이브러리 사용

찬성

  • 자바 스크립트 실행
  • 꽤 빠른

단점

  • 잘못된 렌더링
  • 최근 웹 기능 (FlexBox, 고급 선택기, 웹 폰트, 상자 크기 조정, 미디어 쿼리 등)은 지원하지 않습니다.
  • 규모가 복잡하다
  • 로드 할 이미지가있는 경우 작동하기가 쉽지 않습니다 ...

옵션 3 : Chrome 헤드리스 및 랩퍼 라이브러리 사용

찬성

  • 자바 스크립트 실행
  • 거의 완벽한 렌더링

단점

  • 다음과 관련하여 원하는 결과를 정확하게 얻는 것은 쉽지 않습니다.
    • 페이지로드 타이밍
    • 뷰포트 치수
  • 규모가 복잡하다
  • HTML에 외부 링크가 포함되어 있으면 상당히 느리고 느려집니다.

옵션 4 : API 사용

찬성

  • 자바 스크립트 실행
  • 거의 완벽한 렌더링
  • 캐싱 옵션을 올바르게 사용할 때 빠름
  • 스케일은 API에 의해 처리됩니다
  • 정확한 타이밍, 뷰포트, ...
  • 대부분의 경우 무료 플랜을 제공합니다

단점

  • 많이 사용할 계획이라면 무료가 아닙니다.

면책 조항 : 저는 ApiFlash의 설립자입니다. 나는 정직하고 유용한 답변을 제공하기 위해 최선을 다했습니다.


여기에있는 모든 답변은 타사 라이브러리를 사용하는 반면 HTML을 이미지로 렌더링하는 것은 순수한 Javascript에서 비교적 간단 할 수 있습니다. 되고 도 있었다 그것에 대해 기사 MDN에 캔버스 섹션은.

요령은 다음과 같습니다.

  • XHTML을 포함하는 foreignObject 노드로 SVG를 만듭니다.
  • 이미지의 src를 해당 SVG의 데이터 URL로 설정하십시오.
  • drawImage 캔버스에
  • 캔버스 데이터를 대상 이미지로 설정하십시오.

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

참고할 사항

  • SVG 내부의 HTML은 XHTML이어야합니다
  • 보안상의 이유로 이미지의 데이터 URL 인 SVG는 외부 소스를로드 할 수 없으므로 HTML에 대한 격리 된 CSS 범위로 작동합니다. 그래서 예를 들어 구글 글꼴 같은 도구를 사용하여 인라인해야하는 이 일을 .
  • 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.

You could use PhantomJS, which is a headless webkit (the rendering engine in safari and (up until recently) chrome) driver. You can learn how to do screen capture of pages here. Hope that helps!


You can use an HTML to PDF tool like wkhtmltopdf. And then you can use a PDF to image tool like imagemagick. Admittedly this is server side and a very convoluted process...


The only library that I got to work for Chrome, Firefox and MS Edge was rasterizeHTML. It outputs better quality that HTML2Canvas and is still supported unlike 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);
            }
     });

I don't expect this to be the best answer, but it seemed interesting enough to post.

Write an app that opens up your favorite browser to the desired HTML document, sizes the window properly, and takes a screen shot. Then, remove the borders of the image.


Use this code, it will surely work:

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

Just do not forget to include Html2CanvasJS file in your program. https://html2canvas.hertzen.com/dist/html2canvas.js


You can't do this 100% accurately with JavaScript alone.

There's a Qt Webkit tool out there, and a python version. If you want to do it yourself, I've had success with 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];
}];

Hope this helps!


Use html2canvas just include plugin and call method to convert HTML to Canvas then download as image 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/


Install phantomjs

$ npm install phantomjs

Create a file github.js with following code

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

Pass the file as argument to phantomjs

$ phantomjs github.js

You certainly can. GrabzIt's JavaScript API allows you to capture a div from a webpage like this:

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

Where #features is the ID of the div to capture. If you wanted to convert HTML to a image. You could use this technique:

GrabzIt("Your Application Key").ConvertHTML(
"<html><body><h1>Hello World!</h1></body></html>").Create();

Disclaimer I built this API!


HtmlToImage.jar will be the simplest way to convert a html into an image

Converting HTML to image using java


You can add reference HtmlRenderer to your project and do the following,

string htmlCode ="<p>This is a sample html.</p>";
Image image = HtmlRender.RenderToImage(htmlCode ,new Size(500,300));

참고URL : https://stackoverflow.com/questions/10721884/render-html-to-an-image

반응형