我如何将图像从 url 连同边输入类型文件加载到 html5 canvas?

How can I load image from url along side input type file to html5 canvas?

我正在开发这个应用程序,我需要将图像从 url 和用户的硬盘驱动器上传到 html5 canvas。我已经为用户从硬盘驱动器的输入实现了功能,但我不知道如何从 url.

添加图像

我用来从 input type file 加载的代码都在输入的事件侦听器中。它有很多功能,因为应用程序也需要在图像上输入 text。所以 image from url 也应该具有相同的功能。

请注意 imgObj 在事件侦听器中。我尝试将 img.src 更改为 url 来测试它,但即使图像加载了,我也无法再下载它。控制台抛出此错误:

Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
    at HTMLButtonElement.<anonymous>

这里是去掉一些不需要在这里显示的函数的代码:

const canvas            = document.getElementById('canvas');
const ctx               = canvas.getContext('2d');
const btnDownload       = document.getElementById('btnDownload');
const fileUpload        = document.getElementById('file-upload');

fileUpload.addEventListener('change', function(e) {
    let imgObj          = new Image();
    imgObj.onload       = draw;
    imgObj.onerror      = failed;
    imgObj.src          = URL.createObjectURL(this.files[0]);
    // imgObj.src          = 'https://static.vecteezy.com/system/resources/previews/000/094/478/original/free-abstract-pattern-vector.jpg';
    

    // some functions to write on image

});


function draw() {
    canvas.width        = this.naturalWidth;
    canvas.height       = this.naturalHeight;
    const nw            = this.naturalWidth;
    const nh            = this.naturalHeight;

    ctx.drawImage(this, 0, 0, nw, nh);
};
    
function failed() {
    console.error("The provided file couldn't be loaded as an Image media");
};

btnDownload.addEventListener('click', () => {

    const a = document.createElement('a');
    document.body.appendChild(a);
    a.href = canvas.toDataURL();
    a.download = "canvas-image.png";
    a.click();
    document.body.removeChild(a);

});
<canvas id="canvas" width="800" height="500"></canvas>
<input type="file" id="file-upload" />
<button id="btnDownload">Download</button>

简而言之,我如何通过保留 upload from input 功能来添加 upload from url 功能?

请注意,输入侦听器中的内容对于 upload from url 功能将是相同的。所以可能我必须用 imgObjimg.src.

做点什么

您 运行 遇到了 CORS 问题。 CORS 是一种协议,旨在防止网站从其他站点访问您的数据(跨域 数据)。由于图片自网络早期就存在,因此由于向后兼容性问题无法阻止跨源图像加载,但可能会阻止访问此类数据。

因此,当您将跨源图像绘制到 canvas 中时,canvas 会被“污染”,以至于您无法再用它做很多事情,包括检索它的内容作为数据 URL。从文件系统上传的图像是安全的,因为用户必须选择加入。

所以为了使用图片数据,你必须告诉浏览器必须以跨源方式加载图片。您可以通过设置 crossOrigin 属性或 属性:

<img src="https://static.vecteezy.com/system/resources/previews/000/094/478/original/free-abstract-pattern-vector.jpg" crossorigin>
let imgObj = new Image();
imgObj.src =
      "https://static.vecteezy.com/system/resources/previews/000/094/478/original/free-abstract-pattern-vector.jpg";
imgObj.crossOrigin = "";

有了这个attribute/property,如果图片不支持CORS,就会加载失败,甚至不显示。但如果是这样,就像在本例中一样,您将能够获取图像数据。