Как я могу отменить декодирование изображений в JavaScript?

Чтобы преобразовать данные двоичного изображения (например, из входного файла) в источник изображения холста, можно использовать createImageBitmap или Image.decode .

Есть ли отменяемая альтернатива этим методам?

Я хочу визуализировать изображения из нескольких файловinputкcanvasэлемент, по одному. Мой текущий подход вызывает серьезные задержки, если дополнительные операции декодирования запускаются, пока выполняются предыдущие (меня интересует только результат самой последней).

я узнал чтоImage.decodeможно отменить в некоторых браузерах, повторно установив изображениеsrc. Однако это не работает повсеместно (например, не в Firefox).

Я открыт для использования сторонних библиотек при условии, что они производительны (WebAssembly), бесплатны и поддерживают хотя бы самые основные форматы изображений, такие как JPEG и PNG.

Редактировать

Чтобы прояснить ситуацию, я создал Codepen:https://codepen.io/Tims777/pen/bGxvgBQ .

Просто выберите несколько (более 100) больших (~20 МП) файлов JPEG и некоторое время удерживайте кнопку «вверх», чтобы помучить свой процессор.

1 ответ

Благодаря Даю я теперь могу ответить на свой вопрос:

Использование WebWorker представляет собой довольно простое решение, поскольку рабочий процесс можно отменить прямо в середине выполнения, когда в этом возникнет необходимость.

The worker.jsсамо по себе может быть так просто:

      onmessage = function(event) {
    createImageBitmap(event.data).then(image => postMessage(image));
}

И вот мой переработанныйupdateфункция:

      function update() {
    abortController?.abort();
    abortController = new AbortController();

    if (indexInput.valueAsNumber > fileInput.files.length) return;
    const file = fileInput.files[indexInput.valueAsNumber];
    const signal = abortController.signal;

    const worker = new Worker("worker.js");
    worker.onmessage = (message) => ctx1.drawImage(message.data, 0, 0, canvas1.width, canvas1.height);
    worker.postMessage(file);
    signal.onabort = () => worker.terminate();
}
Другие вопросы по тегам