Почему источник изображения не изменяется сразу после загрузки из «URL.createObjectURL ()»

#javascript #html #image

#javascript #HTML #изображение

Вопрос:

Я написал некоторый код для обработки пикселей изображения. Однако я обнаружил странную проблему. После загрузки изображения из локального файла я должен добавить короткий «спящий режим» перед загрузкой изображения в холст, иначе предыдущее изображение (Firefox) / null будет загружено в холст (Edge). Может кто-нибудь сказать мне, почему это произошло? Спасибо. Код здесь:

  

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>Image Grey Scale Noise</title>
</head>

<body>
  <label for="Selector">Select Image</label>
  <br />
  <input type="file" id="Selector" multiple=false accept="image/*">
  <br />
  <br />
  <label for="greyScale">Grey Scale</label>
  <br />

  <input type="range" id="greyScale" min="0.1" max="10" value="4" step="0.1">

  <p>Image:</p>
  <img id="srcImg" crossOrigin="" src="https://avatars2.githubusercontent.com/u/67770686?s=400amp;u=24015d89e8fab0fb45cad0be3d282f6062e45b5bamp;v=4" />
  <br />
  <img id="outImg" crossOrigin="" src="" />
  <script>
    const fileSelector = document.getElementById('Selector');
    const greyScaleSelector = document.getElementById('greyScale')
    const srcImg = document.getElementById('srcImg');
    const outImg = document.getElementById('outImg');
    var c = document.createElement("Canvas");
    var ctx = c.getContext("2d");
    async function getNewImage(result, greyScale) {
      srcImg.src = resu<
      await new Promise(r => setTimeout(r, 100)); //Without this, the previous image will be loaded...
      c.height = srcImg.height;
      c.width = srcImg.width;
      ctx.drawImage(srcImg, 0, 0);
      var imageData = ctx.getImageData(0, 0, c.width, c.height);
      const data = imageData.data
      var l = data.length;
      for (i = 0; i < l; i  = 4) {
        var r = Math.random() / greyScale   (1 - 1 / greyScale) //Grey Scale Change
        data[i] = Math.min(data[i] * r, 255);
        data[i   1] = Math.min(data[i   1] * r, 255);
        data[i   2] = Math.min(data[i   2] * r, 255);
      }
      ctx.putImageData(imageData, 0, 0);
      outImg.src = c.toDataURL("image/png");
    }
    fileSelector.addEventListener('change', async (event) => {
      var greyScale = greyScaleSelector.value;
      var result = URL.createObjectURL(fileSelector.files[0]);
      await getNewImage(result, greyScale);
      URL.revokeObjectURL(result);
    })
    greyScaleSelector.addEventListener('change', async (event) => {
      var greyScale = greyScaleSelector.value;
      var result = srcImg.src;
      await getNewImage(result, greyScale);
    })
  </script>
</body>

</html> 

Комментарии:

1. это звучит как проблема с синхронизацией: sitepoint.com/jquery-document-ready-plain-javascript вы уверены, что браузер «готов» к запуску вашего JS?

2. @akaphenom Привет, akaphenom, спасибо за своевременный ответ! Мне было интересно, хотите ли вы прокомментировать, если мое понимание неверно. URL.createObjectURL() может потребоваться некоторое время для завершения, и я должен назвать это как обещание или привязать к чему-то вроде событий «DOMContentLoaded»?

3. Лучше всего использовать цепочку событий, загруженных DOM, поскольку это исключает некоторые ошибки условия racde. Если вы добавите это, и это не поможет — тогда ваша проблема в другом месте — но загруженный DOM материал не должен повредить вашему коду — только помочь ему

4. почему бы вам не опубликовать свое решение в качестве ответа?