使用toDataUrl和getImageData正确获取图像,而不会引发安全错误

时间:2019-06-25 14:53:50

标签: canvas cors

  

最后更新

设置

我有三个HTML元素:

<img id="composed-image" class="img-fluid mx-auto d-block" ></img>
<canvas class="hidden" id="canvas-merge"></canvas>
<canvas class="hidden" id="canvas-background"></canvas>

我使用JavaScript从不断变化的来源(picsum.photo,placebear.it等)中加载随机图像,然后将其放入画布背景:下一步:我复制图像从该画布到画布合并,添加一些文本和模糊效果。最后,我将结果复制到合成图像,以使用户可以使用。

(侧面节点:为什么要使用此画布背景?因为我想保留随机选择的图片)

那是我的JavaScript

    var d = new Date();

    var img = new Image();
    img.onload = function() {

        var canvasBackground = document.getElementById('canvas-background');

        canvasBackground.width  = imageWidth;
        canvasBackground.height  = imageHeight;

        var ctxBackground = canvasBackground.getContext('2d');

        ctxBackground.drawImage(image, 0, 0);

        var canvasMerge = document.getElementById('canvas-merge');
        var ctxMerge = canvasMerge.getContext('2d');

        canvasMerge.width  = imageWidth;

        canvasMerge.height  = imageHeight;

        ctxMerge.drawImage(canvasBackground, 0, 0);

        stackBlurCanvasRGBA( 'canvas-merge', 0, 0, imageWidth, imageHeight, $('#image-blur').val());

        var text = $("textarea#text#text").val();
        var fontSize = $("#font-size").val();
        var fontColor = $("#font-color").val();
        var lineHeight = fontSize * 1.2;

        ctxMerge.font = fontSize + "pt WhiteAngelica";

        ctxMerge.fillStyle = fontColor;

        ctxMerge.mlFillText(text, 10, 10, imageWidth, imageHeight, 'top', 'center', lineHeight);

        var imageOutput = new Image();

        imageOutput.src = canvasMerge.toDataURL();

        $("#composed-image").attr('src', imageOutput.src);

    };

    img.crossOrigin = "Anonymous";

    imageSource = "https://picsum.photos/" + imageWidth + "/" + imageHeight + "?" + d;

    img.src = imageSource; 

方案1:工作:

这很好用。如果必须将img.crossOrigin设置为“匿名”,则在调用模糊效果(stackBlurCanvasRGBA)时在Firefox中出现此错误:

  

错误:无法访问图像数据:错误:无法访问本地   图片数据:TypeError:netscape.security。 PrivilegeManager 未定义

但是仍然从远程源加载图像并将其放入画布合并。

场景2:不起作用:

现在我将源更改为

    imageSource = "https://placebeard.it/" + imageWidth + "x" + imageHeight + "?" + d;

这会导致臭名昭著的CORS错误。如果删除crossOrigin设置,则会再次收到上述 PrivilegeManage 错误:

  

错误:无法访问图像数据:错误:无法访问本地   图片数据:TypeError:netscape.security。 PrivilegeManager 未定义

这很奇怪-一次需要CrossOrigin,而另一时间又会产生相同的错误吗?

我可以删除 stackBlur 行,但稍后会在 canvasMerge.toDataURL()处出现错误:

  

SecurityError :操作不安全。

因此,基本上,从picsum.photos加载图片效果很好。但是我尝试了其他一些服务,例如placebeards,backonmockup等,它们都导致了场景2中提到的相同的错误行为。我知道,其主要原因可能是服务器端的CORS标头。但是我不能改变这一点。

所以我的实际问题是:这些错误是如何连接的,为什么CrossOrigin会以这种奇怪的方式运行,并且有解决方法?

更新

我将其固定为:

img.crossOrigin = "Anonymous";

如果没有该行,则将加载所有源,但是处理图像会导致操作不安全

StackBlur的这些​​行有问题:

netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
imageData = context.getImageData( top_x, top_y, width, height );

如果跳过模糊步骤,我会停留在这一行,尝试将图像复制到img标签:

canvasMerge.toDataURL();

我更改了该主题的标题。问题就是这样。

HTML的Canvas和上下文方法getImageData和toDataURL引发安全错误。该如何解决?

仅供参考:在Chrome中为toDataURL();抛出:

Tainted canvases may not be exported.

对于getImageData();我基本上是一样的,只是换句话说:

SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.

在出现这个问题之前:当然,我可以设置img.crossOrigin =“ Anonymous”;但后来我无法从中加载图像placebeard.it。我又回到了最初的问题。

0 个答案:

没有答案