niklasvh / html2canvas

Screenshots with JavaScript
https://html2canvas.hertzen.com/
MIT License
30.62k stars 4.81k forks source link

rendering svg with filled image #1473

Open Naberdz opened 6 years ago

Naberdz commented 6 years ago

Having issue with saving svg which have background image in them.

jQuery('.save').click(function(){
    html2canvas(jQuery('.drawArea')[0], {
        profile: true,
        allowTaint: false,
        useCORS: false,
    }).then(function(canvas){
        var myImage = canvas.toDataURL("image/png");
        .....
    });
});

it can save ordinary svg with filled colors, but when i add background image to it then it becomes empty. any ideas how to solve this issue ?

svg looks like this:

<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="50.000000pt" height="56.000000pt" viewBox="0 0 50.000000 56.000000" preserveAspectRatio="xMidYMid meet" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs><pattern id="image" x="0" y="0" patternUnits="userSpaceOnUse" height="611" width="300"><image x="0" y="0" xlink:href="tmp/image.png"></image></pattern></defs>
<g transform="translate(0.000000,56.000000) scale(0.100000,-0.100000)" fill="#000000" stroke="none">
<path d="M176 531 c-38 -16 -81 -41 -94 -56 -24 -28 -24 -30 -17 -164 l7 -136
89 -90 89 -90 89 90 90 90 7 136 7 136 -29 30 c-16 17 -59 42 -97 57 -37 14
-68 26 -70 25 -1 0 -33 -13 -71 -28z" fill="url(#image)"></path>
</g>
</svg>

Specifications:

adamsvystun commented 5 years ago

Just wanted to ask if there is an update on this? Did somebody find a workaround? (It still does not work for me)

Thanks.

Naberdz commented 5 years ago

I have solved it by using php code. so i don't use html to canvas anymore. don't know where i got this part of the code but here it is :

    jQuery("#save").click(function(){
            var raw = jQuery(".drawArea").html();
            var encoded = raw.replace(/\s+/g, " ");
            encoded = replaceAll(encoded, "%", "%25"); 
            encoded = replaceAll(encoded, "> <", "><"); // normalise spaces elements
            encoded = replaceAll(encoded, "; }", ";}"); // normalise spaces css
            encoded = replaceAll(encoded, "<", "%3c");
        encoded = replaceAll(encoded, ">", "%3e");
            encoded = replaceAll(encoded, "\"", "'");
            encoded = replaceAll(encoded, "#", "%23"); // needed for ie and firefox
            encoded = replaceAll(encoded, "{", "%7b");
            encoded = replaceAll(encoded, "}", "%7d");     
            encoded = replaceAll(encoded, "|", "%7c");
            encoded = replaceAll(encoded, "^", "%5e");
            encoded = replaceAll(encoded, "`", "%60"); 
            encoded = replaceAll(encoded, "@", "%40"); 

            // charset reported as not needed
            var svg = 'data:image/svg+xml;charset=UTF-8,' + encoded;

            var form_data = new FormData();                  
            form_data.append('svg', raw);

            jQuery.ajax({
                url: 'toimage.php', // point to server-side PHP script 
                cache: false,
                contentType: false,
                processData: false,
                data: form_data,                         
                type: 'post',
                success: function(data){
                    //what you do with file is up to you right now my php script returns image
                }
            });
        });
        function escapeRegExp(str) {
        return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
    }

    function replaceAll(str, find, replace) {
        return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
    }

toimage.php :

$svg_data_as_string = $_POST['svg'];
header("Content-Type: image/png");
$image = new IMagick();  
$image->setBackgroundColor(new ImagickPixel('transparent'));  
$image->readImageBlob($svg_data_as_string);  
$image->setImageFormat("png32");