#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. почему бы вам не опубликовать свое решение в качестве ответа?