Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

407
Views
Problem with loading assets into canvas - Uncaught (in promise) DOMException: An attempt was made to use an object that is not, or is no longer usable

I'm trying to load images from my array using the drawImage canvas method. The problem is that it sometimes throws me the following error

Uncaught (in promise) DOMException: An attempt was made to use an object that is not, or is no longer, usable

↑ firefox ↓ google

Uncaught (in promise) DOMException: Failed to execute 'createImageBitmap' on 'Window': The source image width is 0.

Both on index.js:13

Sometimes if I load the page again the error disappears. Does anyone know what could be causing this problem?

My code:

BOE_tile_set.png

(async () => {
    const img = new Image();
    img.src = "./img/BOE_tile_set.png";

    let tiles = [];
    let tileWidth = 28;
    let tileHeight = 36;

    for (let i = 0; i < 77; i++) {
        let x = i % 8;
        let y = Math.floor(i / 8);

        let bmp = await createImageBitmap(img, x * tileWidth, y * tileHeight, tileWidth, tileHeight); // index.js:13

        tiles.push({
            bmp,
            x,
            y
        })
    }

    const canvas = document.querySelector("canvas");
    canvas.width = 224; // img.width
    canvas.height = 360; // img.height

    const ctx = canvas.getContext("2d");
    draw();

    function draw() {
        tiles.forEach((tile) => {
            ctx.drawImage(tile.bmp, tile.x * tileWidth, tile.y * tileHeight);
        })
    }

})();
about 4 years ago · Santiago Gelvez
1 answers
Answer question

0

createImageBitmap(HTMLImageElement) requires that the HTMLImageElement is fully loaded.

So either you do wait for its onload event, or, since it's a bitmap image and not an SVG one, you can await a call to its decode() method which does return a Promise for when the image has been fully loaded and decoded.

(async () => {
  const image = new Image();
  image.src = "https://upload.wikimedia.org/wikipedia/commons/c/cf/Black_hole_-_Messier_87.jpg?" + Math.random();
  try {
    const bmp = await createImageBitmap(image);
  }
  catch(e) {
    console.error("Before load failed:", e.message);
  }
  await image.decode(); // wait for the image to be fully loaded
  const bmp = await createImageBitmap(image);
  console.log("After load succeeded", bmp);
})();

But, still assuming that you are not using an SVG image, and also assuming that you are in a same-origin situation, then the best is to not use an HTMLImageElement at all. Indeed here we just created 2 occurrences of the bitmap data, once for the HTMLImageElement and once for the ImageBitmap. The former isn't going to be used anymore but still consumes computation and memory.

So the best is to fetch your image as a Blob, and call createImageBitmap on that Blob directly:

(async () => {
  const resp = await fetch("https://upload.wikimedia.org/wikipedia/commons/c/cf/Black_hole_-_Messier_87.jpg");
  if (!resp.ok) {
    return console.error("Network error", resp.status);
  }
  const blob = await resp.blob();
  const bmp = await createImageBitmap(blob);
  console.log(bmp);
})();

But once again this requires that your image can be fetched through AJAX (which is certainly the case for you since you use a relative path), and that the image is not an SVG image, because createImageBitmap(Blob) doesn't work with SVG images unless using my polyfill.

about 4 years ago · Santiago Gelvez Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!