1

我正在开发这个应用程序,我需要从 url 和用户的硬盘驱动器将图像上传到 html5 画布。我已经为用户从硬盘驱动器输入实现了功能,但我不知道如何从 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 url通过保留功能来添加upload from input功能?

请注意,输入侦听器内部的upload from url功能将是相同的。imgObj所以可能我必须对and做点什么img.src

4

1 回答 1

1

You're running into a CORS issue. CORS is a protocol meant to prevent websites from getting access to your data from other sites (cross-origin data). Since images were around since the early days of the web, cross-origin image loading couldn't be blocked due to backward compatibility concerns, but getting access to such data could be blocked.

So when you draw a cross-origin image into a canvas, the canvas gets "tainted", such that there are many things you can no longer do with it, including retrieving its contents as a data URL. Images uploaded from the filesystem are safe, since the user has to opt in.

So in order to use the image data, you have to tell the browser that the image must be loaded in a cross-origin manner. You do that by setting the crossOrigin attribute or property:

<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 = "";

With this attribute/property, if the image doesn't support CORS, the load will fail and it won't even display. But if it does, as in this case, you'll be able to get the image data.

于 2021-02-27T09:37:23.010 回答