当我尝试从我的服务器添加图像时,Fabricjs会产生污染画布的问题。

3

我想将服务器上的一张图片添加到画布中并导出它。但是我遇到了这个错误:

未捕获的安全错误:无法在“HTMLCanvasElement”上执行“toDataURL”:受污染的画布不能被导出。

我已经陷入这个困境超过一个星期了,但还没有找到解决方案。

这是我尝试过的方法:

  1. To set the cross origin to anonymous:

    var img = new Image();
    img.onload = function () {
        var imgInstance = new fabric.Image(img, {
            scaleX: 1,
            scaleY: 1
        })
        canvas.add(imgInstance);
    }
    img.src = event.target.result;
    img.crossOrigin = 'Anonymous';
    img.src = 'logo.svg'; // I also tried with full url http://example.com/logo.svg
    

操作未成功。图片已应用到画布上,但无法导出。

  1. Same as 1) but using fabricjs function:

    var src = "logo.svg"; // also tried with http://example.com/logo.svg
    
    fabric.util.loadImage(src, function(img) {
        var object = new fabric.Image(img);
        object.set({ 
            left: 0, 
            top: 0
        });
        object.hasRotatingPoint = true;
        object.scaleX = object.scaleY = 1;
        canvas.add(object);
        canvas.renderAll();    
    }, null, {crossOrigin: 'Anonymous'});
    
  2. With server side (php). Not recommended. BAD IDEA. Works partially but is not ok.

    <?php
        $path = 'http://nistorcristian.com/comixer/logo.svg';
        $type = pathinfo($path, PATHINFO_EXTENSION);
        $data = file_get_contents($path);
        $base64 = 'data:image/svg+xml;/' . $type . ';base64,' . base64_encode($data);
    ?>
    
    fabric.Image.fromURL('<?=$base64?>', function(obj2) {
        canvas.add(obj2);
    });
    
  3. Set the .htaccess:

    <IfModule mod_headers.c>
         Header set Access-Control-Allow-Origin "*"
    </IfModule>
    

    OR:

    <FilesMatch "\.(svg|svgz)$">
      SetEnvIf Origin »
        "^http(s)?://(.+\.)?(example\.com)$" origin_is=$0
      Header set Access-Control-Allow-Origin %{origin_is}e env=origin_is
    </FilesMatch>
    
  4. I tried to define in my php file the header:

    header("Access-Control-Allow-Origin: *");
    

仍没有好运。任何帮助都将不胜感激 :) 谢谢


img.src = event.target.result; 这行代码不应该存在(但可能无法解决问题)。SVG 引用了外部文件吗(如 foreign objects、样式表等)? - user1693593
没有问题...但是我阅读了更多的资料,发现目前不支持在SVG被污染后导出画布(只有在Firefox中可以)。使用jpeg或png在所有浏览器中都可以正常工作,但是SVG不行。也许将来会有所改进。感谢你的回答,Ken。 - Nistor Cristian
1个回答

1

好的...我刚刚发现。我在fabricjs的演示中看到(http://fabricjs.com/kitchensink/),他们能够导出svg...所以我查看了他们的代码,我看到了这个:

var addShape = function(shapeName) {

    console.log('adding shape', shapeName);

    var coord = getRandomLeftTop();

    fabric.loadSVGFromURL('../assets/' + shapeName + '.svg', function(objects, options) {

      var loadedObject = fabric.util.groupSVGElements(objects, options);

      loadedObject.set({
        left: coord.left,
        top: coord.top,
        angle: getRandomInt(-10, 10)
      })
      .setCoords();

      canvas.add(loadedObject);
    });
  };

我刚刚修改了代码,现在它可以正常工作了。终于解决了。


这个 URL "http://example.com/logo.svg" 发生了什么?你如何应用它? - AbingPj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接