I have to apply some styles on <img>
thanks to a CSS class.
Is it possible to get the dataURL
of the <img>
with the CSS style ?
$(function() {
// Original
const imgOriginal = document.getElementById('original');
const c1 = document.getElementById('c1');
let ctx = c1.getContext('2d');
ctx.drawImage(imgOriginal, 100, 100);
// Filtered
const imgFiltered = document.getElementById('filtered');
const c2 = document.getElementById('c2');
ctx = c2.getContext('2d');
ctx.drawImage(imgFiltered, 100, 100);
// Same dataURL :(
console.log(c1.toDataURL(), c2.toDataURL());
console.log(c1.toDataURL() === c2.toDataURL());
})
.filter::before {
display: block;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 1;
border: 1px solid red;
}
.filter {
position: relative;
-webkit-filter: sepia(.5) hue-rotate(-30deg) saturate(1.4);
filter: sepia(.5) hue-rotate(-30deg) saturate(1.4);
}
canvas {
display: block;
width: 100px;
height: 100px;
border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<img id="original" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg/170px-Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg">
<canvas id="c1"></canvas>
<img id="filtered" class="filter" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg/170px-Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg">
<canvas id="c2"></canvas>
</div>
Maybe snippet is going to have a bug because of the <canvas>
tag, the idea is there anyway.
EDIT :
If anyone has a suggestion with SVG
or something else, I'm using fabricJS.
EDIT 2 (NOT RESOLVE BUT FIND OTHER WAY) :
Thanks to @KavianK. you could replicate CSS
style with the canvas
context, however to me it's boring because we have to store a different callback
for each CSS
class to get the dataURL
. Working anyway!
Thanks to @Emeeus maybe a solution provide from your backend, not solution for me beacause i'm want to do this ONLY on the front-end. wkhtmltopdf
Thanks to @pegasuspect we can filter an image with SVG
, I'm following this way and I replace fabricJS by svgjs, this librairie can replace easly a canvas
and it's more easier to work with img
and I dind't need the DataURL
anymore !
Thanks to @Kaiido there is a way to take a snapshot
of your HTML
rendered with CSS
style with html2canvas easy to get dataURL
with this case. Unfortunataly some CSS
styles are not supported yet like box-shadow
or filter
that's why it's not a solution for me
This topic is not resolve but with svgjs
I don't need actually work with dataURL
.
CSS
and DOM
is a separate world from the bitmaps that are used for images and canvas. The bitmaps themselves are not affected by CSS
, only the elements which acts as a looking-glass to the bitmap. So, CSS filters applied to the canvas will not be applied to the image that is produced. You either need to replicate the filters in canvas or rather re apply the same filters to the generated image.
Example:
There is a little known property on the context object, conveniently named filter. This will apply a filter on the context it self. The filter must be set before next draw operation.
var img = new Image();
img.crossOrigin = '';
img.src = document.getElementById( 'original' ).src;
img.onload = function() {
var canvas = document.getElementById( 'canvas' ),
ctx = canvas.getContext( '2d' );
canvas.width = this.width;
canvas.height = this.height;
// filter
if ( typeof ctx.filter !== 'undefined' ) {
ctx.filter = "sepia(.5) hue-rotate(-30deg) saturate(1.4)";
ctx.drawImage(this, 0, 0);
} else {
ctx.drawImage(this, 0, 0);
}
document.getElementById( 'filtered' ).src = canvas.toDataURL();
}
<img id="original" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg/170px-Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg" />
<img id="filtered" />
<canvas id="canvas" style="display: none"></canvas>
You can do it with SVG. http://jsfiddle.net/1hambw93/91/
It is explained here quite nicely. It basically says you can use svg element in src tag of an img
.
It is explained here quite nicely as well: I could achieve the same filter effect with your code, using an SVG filter.
You can generate filter for svg from this site using Sepium to get the same filter as your css. You would have the following SVG so far:
<svg id="test">
<image xlink:href='https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg/170px-Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg'
x="0" y="0" height="170px" width="218px"
filter='url(#sepium-filter)' />
<filter id="sepium-filter">
<feColorMatrix type="matrix"
values="1.3 -0.3 1.1 0 0
0 1.3 0.2 0 0
0 0 0.8 0.2 0
0 0 0 1 0">
</feColorMatrix>
</filter>
</svg>
Then I used a minimal javascript code to convert to base64 and write the result from the SVG to an object, to display in HTML.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With