Adding img.crossOrigin = “*” interferes with img.complete

假装没事ソ 提交于 2021-01-29 05:20:05

问题


I have a function that reads map tile images. I want to keep track of whether or not a certain image has already been cached. I'm using this function from this thread:

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

    return image.complete;
}

This was working great. But then I needed to do some image processing. In order to copy the image data to a canvas and process it pixel by pixel, I need to use CanvasRenderingContext2D.drawImage(image, 0, 0). But it bugs me with a cross-origin error. So I can add a image.crossOrigin = "*", which solves that problem, and I can write to a canvas and do the image processing I need. That bit looks like this:

  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)
  }

The issue that arises is that every time I run the larger function which contains these two bits of code, the is_cached function returns false every time, except the first time. But I know that even though is_cached is returning false, the images are indeed cached, as they are loading with 0 lag (as opposed to when a novel image is called and it takes a moment to grab it from the server).

Why might .crossOrigin = "*" be interfering with the .complete status of an image?

This is happening within an ObservableHQ notebook. Might that have something to do with it? ObservaleHQ gets weird sometimes.

ObservableHQ Notebook with the problem

You can find this code in the getTileUrl cell at the bottom. This notebook is not yet finished. You can see the cached status at the Tile Previously Cached line after you click around the map of submit changes to the inputs.

Thanks for reading.


回答1:


Maybe fetch api can enforce cache using the param {cache:"force-cache"}, however images should be cached as expected. You can fetch the image and pass its blob as an image source.

replace your imageOutput.src with

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

make your getTileURL function async as we have to await fetch and blob to be ready to be passed as image source

  async function getTileURL(latArg, lngArg, zoomArg) {

Use devtools to inspect network and see tile images coming from disk cache

edit:

just try your original code and inspect network via devtools. The tiles images are cache as expected. So no need to hack into fetch blob src.



来源:https://stackoverflow.com/questions/61691336/adding-img-crossorigin-interferes-with-img-complete

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!