当前位置:  开发笔记 > 编程语言 > 正文

将SVG转换为PNG,将应用的图像作为svg元素的背景

如何解决《将SVG转换为PNG,将应用的图像作为svg元素的背景》经验,为你挑选了1个好方法。

我有一个外部SVG文件,其中包含一些模式中嵌入的图像标记.每当我使用此SVG转换为PNG时toDataURL(),生成的PNG图像不包含我作为模式应用于某些SVG路径的图像.有什么方法可以解决这个问题吗?



1> Kaiido..:

是的,有:将svg附加到您的文档中,并将所有包含的图像编码为dataURI.

我正在编写一个执行此操作的脚本以及其他一些内容,例如包括外部样式表以及toDataURL将失败的其他一些修复(例如,通过xlink:href属性引用的外部元素).

这是我为解析图像内容而编写的函数:

function parseImages(){
    var xlinkNS = "http://www.w3.org/1999/xlink";
    var total, encoded;
    // convert an external bitmap image to a dataURL
    var toDataURL = function (image) {

        var img = new Image();
        // CORS workaround, this won't work in IE<11
        // If you are sure you don't need it, remove the next line and the double onerror handler
        // First try with crossorigin set, it should fire an error if not needed
        img.crossOrigin = 'Anonymous';

        img.onload = function () {
            // we should now be able to draw it without tainting the canvas
            var canvas = document.createElement('canvas');
            canvas.width = this.width;
            canvas.height = this.height;
            // draw the loaded image
            canvas.getContext('2d').drawImage(this, 0, 0);
            // set our 's href attribute to the dataURL of our canvas
            image.setAttributeNS(xlinkNS, 'href', canvas.toDataURL());
            // that was the last one
            if (++encoded === total) exportDoc();
        };

        // No CORS set in the response      
        img.onerror = function () {
            // save the src
            var oldSrc = this.src;
            // there is an other problem
            this.onerror = function () {
                console.warn('failed to load an image at : ', this.src);
                if (--total === encoded && encoded > 0) exportDoc();
            };
            // remove the crossorigin attribute
            this.removeAttribute('crossorigin');
            // retry
            this.src = '';
            this.src = oldSrc;
        };
        // load our external image into our img
        img.src = image.getAttributeNS(xlinkNS, 'href');
    };

    // get an external svg doc to data String
    var parseFromUrl = function(url, element){
        var xhr = new XMLHttpRequest();
        xhr.onload = function(){
            if(this.status === 200){
                var response = this.responseText || this.response;
                var dataUrl = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(response);
                element.setAttributeNS(xlinkNS, 'href', dataUrl);
                if(++encoded === total) exportDoc();
                }
            // request failed with xhr, try as an 
            else{
                toDataURL(element);
                }
            };
        xhr.onerror = function(){toDataURL(element);};
        xhr.open('GET', url);
        xhr.send();
        };

    var images = svg.querySelectorAll('image');
    total = images.length;
    encoded = 0;

    // loop through all our  elements
    for (var i = 0; i < images.length; i++) {
        var href = images[i].getAttributeNS(xlinkNS, 'href');
        // check if the image is external
        if (href.indexOf('data:image') < 0){
            // if it points to another svg element
            if(href.indexOf('.svg') > 0){
                parseFromUrl(href, images[i]);
                }
            else // a pixel image
                toDataURL(images[i]);
            }
        // else increment our counter
        else if (++encoded === total) exportDoc();
    }
    // if there were no  element
    if (total === 0) exportDoc();
}

这里svgDoc叫svg,
exportDoc()功能可能只是被写成:

var exportDoc = function() {
    // check if our svgNode has width and height properties set to absolute values
    // otherwise, canvas won't be able to draw it
    var bbox = svg.getBoundingClientRect();

    if (svg.width.baseVal.unitType !== 1) svg.setAttribute('width', bbox.width);
    if (svg.height.baseVal.unitType !== 1) svg.setAttribute('height', bbox.height);

    // serialize our node
    var svgData = (new XMLSerializer()).serializeToString(svg);
    // remember to encode special chars
    var svgURL = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData);

    var svgImg = new Image();

    svgImg.onload = function () {
        var canvas =  document.createElement('canvas');
        // IE11 doesn't set a width on svg images...
        canvas.width = this.width || bbox.width;
        canvas.height = this.height || bbox.height;

        canvas.getContext('2d').drawImage(svgImg, 0, 0, canvas.width, canvas.height);
        doSomethingWith(canvas)
    };

    svgImg.src = svgURL;
};

但是再一次,你必须首先将你的svg附加到文档中(通过xhr或者一个