在 Javascript 中将外部托管的图像转换为数据 URI

问题描述

我正在构建一个从网页上的容器 div 创建画布的函数。我遇到了一个问题,由于 COR,站点图像是“外部图像”,因此不允许出现在画布上。

它们是“外部图像”,因为我们正在使用站点构建器/主机 (https://www.knack.com/) 将所有上传的图像放入他们的 AWS 存储桶中。如果我将图像上传到“mysite.com”,他们会将它们作为 aws 托管图像保存到数据库中。这使得图像 src = "https://s3.amazonaws.com/assets.knackhq.com/assets/numbers/numbers/original/filename.jpg"。

图像在浏览器中都显示正常,但在尝试创建画布时出现 COR 错误

现在,我找到了一个解决方法”。如果我将图像 url 转换为数据 URI,则图像会毫无问题地添加到画布中。

不过,解决方法存在问题。通过在线转换器站点手动发送 url 有效,但对于我们拥有的图像数量是不可行的,因为我们将不断添加更多图像。我尝试了很多使用 JS 将图像转换为数据 URI 的方法,但到目前为止,由于 COR 错误,这些方法也一直失败。

简而言之:

  • 我想将图像转换为干净的画布,但我不能,因为它们是外部图像
  • 由于我正在使用的网站的限制和流程,我无法将图像作为外部图像处理
  • 我无权访问服务器以更改有关 COR 的设置或在服务器上设置任何类型的转换器
  • 如果我将外部图像转换为数据 URI,它们会很好用
  • 我需要动态转换图像,因为手动转换每个图像然后编码是不可行的
  • 我无法将外部图像动态转换为数据 URI

有谁知道在 JS 或转换器 API 中执行此操作的工作方法,我可以在我的代码调用以执行转换?或者任何其他解决方案?我对任何可以处理我在此处列出的约束条件的事物都持开放态度。

解决方法

Sideshowbarker 为我提供了一份有关解决此问题的 COR 代理的指南!

我在图像 url 前面使用了 CORs 代理 (https://api.codetabs.com/v1/proxy?quest=),然后通过画布将它们运行到 dataURL 函数:

function replace_img(url,img_2_replace) {
    // To bypass errors (“Tainted canvases may not be exported” or “SecurityError: The operation is insecure”)
    // The browser must load the image via non-authenticated request and following CORS headers
    var img = new Image();
    img.crossOrigin = 'Anonymous';
    img.src = url;
    // The magic begins after the image is successfully loaded
    img.onload = function () {
    var canvas = document.createElement('canvas'),ctx = canvas.getContext('2d');

    canvas.height = img.naturalHeight;
    canvas.width = img.naturalWidth;
    ctx.drawImage(img,0);

    // Unfortunately,we cannot keep the original image type,so all images will be converted to PNG
    // For this reason,we cannot get the original Base64 string
    var uri = canvas.toDataURL('image/jpg'),b64 = uri.replace(/^data:image\/jpg;base64,/,"");

    //console.log(b64); //-> "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWP4z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg=="
    var replace = document.getElementById(img_2_replace);
    replace.src= b64;  
    };
    

    }

dataURI 函数的一部分是用 dataURI 替换 DOM 中的 img src。这避免了 COR 错误,并为我提供了数据 URI 图像,当我将画布转换为 PDF 时,我可以保留这些图像。