I use SVG to apply filters and patterns to images (need it for printing). My issue is that when I draw the svg to canvas in order to save it as jpeg, the linked image and pattern doesn't show on canvas.
From what I have observed, if I convert the image URL to base64 (for "embedding" it into the SVG) the image shows up on canvas, but I can't do the same thing to the fill property ( fill="url(#dots)"
).
I wonder, is there a way to "rasterize" the svg before I load it into the canvas, or how could I get linked properties to show up on canvas?
this is how svg looks in the browser:
<svg viewBox="0 0 340 415" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" version="1.1" preserveAspectRatio="xMidYMid slice">
<defs>
<pattern id="dots" x="0" y="0" width="1" height="1">
<image xlink:href="/data/img/patterns/dots.jpg" x="0" y="0" width="100%" height="100%" preserveAspectRatio="xMidYMid slice"/>
</pattern>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="url(#dots)"></rect>
<image xlink:href="blob:http://localhost:8081/a80eac2b-722b-4596-99b1-38d2646761f6" id="image" x="4mm" y="4mm" width="82mm" height="82mm" preserveAspectRatio="xMidYMid slice" filter="url(#walden)"></image>
<text id="note" x="4.5cm" y="10.2cm" text-anchor="middle" font-size="30px" font-family="Pacifico"><!---->Hello World!<!----></text>
</svg>
My code for saving the svg to file:
export(){
var svg = this.shadowRoot.querySelector('svg');
var xml = (new XMLSerializer).serializeToString(svg);
var svg64 = 'data:image/svg+xml;base64,' + btoa(xml);
var viewbox = svg.getAttribute('viewBox');
var canvas = document.createElement("canvas");
var width = viewbox.split(' ')[2],
height = viewbox.split(' ')[3],
ctx = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
ctx.clearRect(0, 0, width, height); // clear canvas
var img = new Image();
img.onload = function () {
ctx.drawImage(img, 0, 0);
canvas.toBlob((b)=>{
that.upload(b);
});
document.body.appendChild(img); //for visualising the results
};
img.src = svg64;
}
rezults (top: svg, bottom: canvas render)
The only solution I have found for the same problem is to include the patterns inside the svg in base64 encoding:
<pattern id="pat01" xlink:href="data:image/png;base64,iVBOR...CC " style="opacity:1;stop-opacity:1" /></pattern>
...
<circle cx="23" cy="153" r="18" style="opacity:1;fill:url(#pat01);fill-opacity:1;stop-opacity:1;stroke:#000000;stroke-miterlimit: 10;"></circle>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.