Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get png image of a CSS styled element using canvas with transparent background?

I want to use CSS to style an element on a webpage and then to use that element as a static png. Is it possible to draw html node on eg. canvas and save such image with transparency to a file?

I want to find a way to take already existing HTML with CSS and render it to PNG file keeping transparency.

like image 747
Łukasz Avatar asked Feb 19 '13 14:02

Łukasz


2 Answers

Saving HTML elements to images requires a Complicated Answer!

First, for very good security reasons, browsers do not to allow same-page imaging of HTML elements. Imagine for example a malicious script that takes the HTML input form containing your banking username+password and converts it to an image and sends the image to a thief—not good!

Therefore, IE simply block same page HTML element imaging--period.

Chrome and Firefox might still have a feature (bug?!) that allows you to turn HTML elements into images like this: 1. Embed the HTML element into an SVG element using "foreignObject". 2. Draw the SVG element into a Canvas element. 3. Use canvas.toDataURL(‘image/png’) to get an encoded string representing the png image.

Since it looks like you are in control of styling the HTML, you might have a full solution by using a “headless” HTML generator like PhantomJs.org (phantomjs.org). You can use Phantomjs to generate and style the HTML element. PhantomJs then has a rasterizer you can use to convert that element into an image. Plus, If you can serve up a web page that contains only the styled HTML you need, then this 1 line of PhantomJs code will get you a png of that page:

phantomjs rasterize.js http://myHtmlOnMyPage.html myHtmlImage.png

The Chrome/Firefox code is found here: https://developer.mozilla.org/en-US/docs/HTML/Canvas/Drawing_DOM_objects_into_a_canvas

And looks like this:

<!DOCTYPE html>
<html>
<body>
<p><canvas id="canvas" style="border:2px solid black;" width="200" height="200"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var data = "<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'>" +
             "<foreignObject width='100%' height='100%'>" +
               "<div xmlns='http://www.w3.org/1999/xhtml' style='font-size:40px'>" +
                 "<em>I</em> like <span style='color:white; text-shadow:0 0 2px blue;'>cheese</span>" +
               "</div>" +
             "</foreignObject>" +
           "</svg>";
var DOMURL = self.URL || self.webkitURL || self;
var img = new Image();
var svg = new Blob([data], {type: "image/svg+xml;charset=utf-8"});
var url = DOMURL.createObjectURL(svg);
img.onload = function() {
    ctx.drawImage(img, 0, 0);
    DOMURL.revokeObjectURL(url);
};
img.src = url;
</script>
</body>
</html>
like image 109
markE Avatar answered Sep 23 '22 04:09

markE


Just found an easy way via Safari.

Right click on element, Inspect Element, then in the Inspector right click on the element node you want to export and pick Capture Screenshot. This to me resolves transparency. Safari Version 13.1 (14609.1.20.111.8)

enter image description here

like image 21
PEZO Avatar answered Sep 25 '22 04:09

PEZO