添加img.crossOrigin =“ *”会干扰img.complete

时间:2020-05-09 03:16:18

标签: javascript image-processing caching canvas observablehq

我有一个读取地图图块图像的功能。我想跟踪某个图像是否已经被缓存。我正在使用this thread中的此功能:

function is_cached(src) {
    var image = new Image();
    image.src = src;

    return image.complete;
}

这很好。但是然后我需要做一些图像处理。为了将图像数据复制到画布并逐像素处理它,我需要使用CanvasRenderingContext2D.drawImage(image, 0, 0)。但这使我产生了跨域错误。因此,我可以添加一个image.crossOrigin = "*"来解决该问题,并且可以写到画布上并进行所需的图像处理。那有点像这样:

  imageOutput.crossOrigin = "*"
  var demCtx;
  imageOutput.onload = function(){
    var c = document.createElement('canvas')
    c.width = c.height = 256
    demCtx = c.getContext('2d')
    demCtx.drawImage(imageOutput, 0, 0)
    var imageData = demCtx.getImageData(0, 0, 256, 256)
  }

出现的问题是,每次我运行包含这两位代码的较大函数时,is_cached函数每次都会返回false,但第一次除外。但是我知道,即使is_cached返回的是false,这些图像的确也已缓存,因为它们的加载延迟为0(与调用一个新颖的图像相反,从服务器上抓取图像需要花费一些时间)

为什么.crossOrigin = "*"会干扰图像的.complete状态?

这是在ObservableHQ笔记本中发生的。可能与它有关吗? ObservaleHQ有时会变得很奇怪。

ObservableHQ Notebook with the problem

您可以在底部的getTileUrl单元格中找到此代码。该笔记本尚未完成。单击地图将更改提交到输入后,您可以在Tile Previously Cached行看到缓存的状态。

感谢阅读。

1 个答案:

答案 0 :(得分:0)

也许fetch api可以使用参数{cache:"force-cache"}强制执行缓存,但是应该按预期的方式缓存图像。您可以获取图像并将其斑点作为图像源传递。

替换您的imageOutput.src
    imageOutput.src = URL.createObjectURL(await fetch(imageUrl, {cache:"force-cache"}).then(r => r.blob()));

使您的getTileURL函数async成为可能,因为我们必须等待提取和Blob才能准备好作为图像源传递

  async function getTileURL(latArg, lngArg, zoomArg) {

使用devtools检查网络并查看来自磁盘缓存的图块图像

编辑:

只需尝试使用原始代码并通过devtools检查网络。切片图像将按预期进行缓存。因此,无需入侵获取blob src。