Преобразование ArrayBuffer в blob

У меня есть проект, где мне нужно отображать схемы djvu в браузере.

Я нашел эту старую библиотеку в Github, которая, насколько я понял, преобразует файлы djvu в bmp и затем помещает их в элемент canvas.

Как я уже сказал, библиотека устарела (последняя фиксация была 5 лет назад), поэтому мне нужно внести некоторые исправления. Основная проблема заключается в том, что lib использует устаревший BlobBuilder.

Шаги, которые я предпринял для решения этой проблемы:

  • Декомпрессировать эту библиотеку через Chrome DevTools
  • Исходная ошибка находится в строке 3774 var c = "undefined" != typeof MozBlobBuilder ? MozBlobBuilder : "undefined" != typeof WebKitBlobBuilder ? WebKitBlobBuilder : console.log("warning: cannot build blobs")
  • Я прокомментировал эту строку
  • Затем я прокомментировал строку c = new c; и некоторые из следующих строк.

Итак, теперь это выглядит так (переменная я является буфером массивов, а ololo1 и ololo2 - своего рода смещение и ограничение)

var c = new Blob(new Uint8Array(new Uint8Array(I,ololo1,ololo2)))
              , b = b.createObjectURL(c)
              , c = document.getElementById(kb)
              , f = c.getContext("2d")
              , h = new Image
              , g = a[Ea >> 2]
              , i = a[Fa >> 2]
              , j = c.width
              , k = Math.round(i * j / g);

            h.onload = function()
            {
                var a = g / j;
                4 < a && (a = 4);
                1 > a && (a = 1);
                f.globalAlpha = 1;

                for (N = 0; N < a; N++)
                    f.drawImage(h, N, N, g - a + N, i - a + N, 0, 0, j, k),
                    f.globalAlpha *= 1 - 1 / a;
                R(h.complete, "Image /bmp.bmp could not be decoded")
            }
            ;
            h.onerror = function(errorMsg, url, lineNumber, column, errorObj) {
                console.log(errorMsg, url, lineNumber, column, errorObj);
                console.log("Image /bmp.bmp could not be decoded!")
            }           
            ;

И теперь я застрял в ошибке "Изображение/bmp.bmp не может быть расшифровано!" (выбрано в обработчик h.onerror).

Итак, мой вопрос: что я делаю неправильно?

Ответ 1

Я не знаю, почему автор Uint8Array свой Uint8Array в новый... обратите внимание, что я не знаю ни одного устаревшего API BlobBuilder, но одна опечатка, которую я вижу в вашем коде, заключается в том, что вам нужно обернуть свой TypedArray в обычном массиве:

new Blob([new Uint8Array(buffer, byteOffset, length)]);

Конструктор Blob принимает последовательность blobParts в качестве первого параметра, а затем выполняет поиск элементов BufferSource, USVStrings и Blob в этой последовательности. Поэтому, когда вы передаете TypedArray, он фактически перебирает все записи этого TypedArray и обрабатывает их как USVString (и, таким образом, преобразует их числовое значение в строки UTF-8 в Blob). Это редко, что вы хотите, так что лучше всегда передавать массив в этом конструкторе.

Ответ 2

var buffer = new ArrayBuffer(32);

new Blob([buffer]);

поэтому массив Uint8Array должен быть

new Blob([new Uint8Array([1, 2, 3, 4]).buffer]);