【问题标题】:Downloading a tainted canvas as a PNG将受污染的画布下载为 PNG
【发布时间】:2020-05-18 11:22:06
【问题描述】:

我正在尝试制作一个按钮,当按下该按钮时,它会将画布元素下载为 PNG 文件。

function downloadImage(canvas)
{
    let url = canvas.toDataURL("image/png");
    window.open(url);
}

此代码适用于未污染的画布,但我尝试下载图像的画布已被污染,因此我无法在其上运行 .toDataURL()。我见过的许多处理受污染的画布的线程都与创建画布的图像显示有关,但是有没有办法直接下载它而不创建中间图像元素?

我的网站非常简单,目前我没有在任何服务器上运行它(只是在谷歌浏览器中打开 index.html 文件)。但是,我也不想更改任何本地浏览器设置,因为我希望它在多个不同的浏览器上运行。

【问题讨论】:

  • 所以你正在使用file:/// 协议做所有事情?没有来自其他网站的外部图片?使用 firefox,它不认为file:/// 是跨域
  • 我在调试时在 file:/// 环境中工作,但最终我确实想将它发布到 Github Pages,在那里来自不同浏览器的人们将访问它,所以改变浏览器不完全适合我。
  • 对,那么在 github 页面中,图片会是同源的吗?
  • 图片是直接上传到网站上的,不存储在任何地方,而画布是通过对图片进行操作制成的,所以我认为答案是肯定的。
  • 那么一旦你摆脱了file:///协议,你就不会遇到问题了——使用本地http服务器进行开发——使用nodejs或python非常简单

标签: javascript html


【解决方案1】:

问题在于 JavaScript 旨在让您不下载任何受污染的图像。

但是,这可以被规避。您在问题中提到您正在使用文件协议;但是,在 cmets 中提到,您最终将愿意在 github pages 上使用 Web 服务器,因此,如果我们在这种情况下工作,也许我们可以完成这项工作。

首先,再次直接回答您的问题,如何下载已被操纵的受污染画布,正式浏览器的设计方式旨在防止这种情况发生,请参阅 https://stackoverflow.com/a/36905778/2016831 了解更多信息.

所以现在寻找可能的解决方法。

这取决于画布被污染的原因,是在您的代码访问它之前在上面绘制的东西,还是您的代码首先使其受到污染?

如果它是第二个选项,那么,如引用的答案中所述,您可以做几件事。

首先,尝试在 JavaScript 中的图像元素上添加属性crossOrigin = "anonymous",这可能适用于某些网站。

不过,对于其他人,您可以使用 nodeJS 或 PHP 或任何其他服务器端语言设置一个简单的服务器,该服务器可以漂亮地托管在任何托管平台上,该平台将对给定的图像 URL 发出 HTTP 请求,下载它并返回到您的客户端文件,将 access-control-allow-origin 设置为*,但是,正如答案中提到的那样,这会占用更多带宽,但如果带宽不是问题,那么您可以这样做。

当然,您也可以让用户简单地通过文件输入而不是 URL 上传图像,但这会限制可用性。

与提到的第一个“crossOrigin”解决方案相关的另一种选择是,如果图像来自允许跨域请求的站点,您可以先使用 fetch 下载它,然后从 blob 数据中创建一个对象 URL,并将图像的来源设置为,然后当图像加载时,将其绘制到画布上,基本上

fetch("someURLtoAnImageOnaSiteThatAllowsCrossOriginRequests")
.then(result => result.blob())
.then(blob => {
    myImageElement.src = URL.createObjectURL(blob);
    myImageElement.onload = startDrawingImageToCanvasFunction;
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-07
    • 2018-02-11
    • 2019-04-14
    相关资源
    最近更新 更多