将svg保存为png,其中svg包含带有外部引用的图像

时间:2016-02-18 05:17:17

标签: jquery cross-domain canvg

我有一个SVG,其中有许多图像标签指向外部图像源(来自amazon s3 bucket)。我想把它转换成像这样的png

canvg(document.getElementById('myCanvas'), svg);
 var imgData = document.getElementById('myCanvas').toDataURL("image/png");

我收到此错误未捕获的安全错误:无法执行' toDataURL' on' HTMLCanvasElement':可能无法导出受污染的画布。

我更改了s3存储桶设置(As mentioned here)。 在canvg函数

之后添加了这段代码
var img = new Image();
    img.setAttribute('crossOrigin', 'anonymous');
    img.src = document.getElementById('myCanvas').value;

甚至尝试迭代所有图像标记并设置crossOrigin属性

我仍然得到同样的错误。

1 个答案:

答案 0 :(得分:2)

我发现在服务器端进行转换更好,因为允许amazon s3中的交叉起源是一种安全威胁,即使给出了跨域权限,许多浏览器也不支持.toDataUrl。

这就是我进行转换的方式

在客户端

var s = new XMLSerializer().serializeToString(document.getElementById("svg"))
var encodedData = window.btoa(s);

这个编码数据传递到服务器端,在那里我使用batik库实际转换svg到png

BASE64Decoder decoder = new BASE64Decoder();
    byte[] image = decoder.decodeBuffer(encodedData);
    String fileLocation  = "C:\temp";
    String fileName = "New-" + System.currentTimeMillis();
    File file = new File(fileLocation +File.separator+ fileName + ".svg");
    FileOutputStream fop = new FileOutputStream(file);
    if (!file.exists()) {
      file.createNewFile();
    }
    fop.write(image);
    fop.flush();
    fop.close();
    PNGTranscoder transcoder = new PNGTranscoder();
    TranscoderInput tinput = new TranscoderInput(new FileInputStream(fileLocation + File.separator + fileName +".svg"));
    OutputStream ostream = new FileOutputStream(fileLocation + File.separator + fileName +".png");
    TranscoderOutput toutput = new TranscoderOutput(ostream);
    try {
          transcoder.transcode(tinput, toutput);
    } catch (TranscoderException e) { 
          System.out.println("error*");
           e.printStackTrace();
    }
    ostream.close();