Как создать массив canvas imageData из представления ArrayBuffer JPG

прежде всего, я знаю, что существуют стандартные методы достижения этого (readAsDataURL и drawImage), но, к сожалению, они не используются для этого конкретного случая использования.

Я читаю изображение, используя API filereader в качестве arraybuffer, например:

    var reader = new fileReader();
    reader.onload = function(e){

          var byteArray = new Uint8ClampedArray(e.target.result);
          //do stuff to this array
    }
    reader.readAsArrayBuffer(file);

затем я создаю clampedarray с этими возвращенными данными.

то, что я хочу сделать, это нарисовать этот пиксельный массив непосредственно на холсте с помощью putImageData

В настоящее время я делаем следующее:

var byteArray = new Uint8ClampedArray(e.target.result);
var imgdata = ctx.createImageData(img.width, img.height);
var canvdata = imgdata.data;

for (var i = 0; i < canvdata.length; i += 4) {
    canvdata[i] = byteArray[i];
    canvdata[i + 1] = byteArray[i + 1];
    canvdata[i + 2] = byteArray[i + 2];
    canvdata[i + 3] = byteArray[i + 3];
}
ctx.putImageData(imgdata, 0, 0);

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

это заставляет меня полагать, что я неправильно строю данные imagedata в моем цикле или, возможно, мой первоначальный метод получения массива пикселей неверен.

подводя итог, я хотел бы иметь возможность взять arraybuffer (jpeg), полученный через html5 FileReader API, а затем создайте совместимый с холстом массив imageData, чтобы позже его можно было вставить в холст с помощью putImageData

спасибо заранее.

1 ответов


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

A в формате JPEG файл не является простым байтовым массивом цветных данных, и поэтому вы не можете просто загрузить его так. Если вы хотите обойти это без импорта непосредственно в холст, вам придется использовать в формате JPEG библиотека декодирования, например этот проект от notmasteryet который я нашел с помощью быстрого поиска google.

Оригинал

к сожалению, они не используются для этого конкретного случая использования

почему они не используются?

// example array
u = new Uint8ClampedArray(4);
u[0] = 255, u[1] = 56, u[2] = 201, u[3] = 8; // [255, 56, 201, 8]
// to String
str = String.fromCharCode.apply(null, u); // "ÿ8É"
// to Base64
b64 = btoa(str); // "/zjJCA=="
// to DataURI
uri = 'data:image/jpeg;base64,' + b64; // "data:image/jpeg;base64,/zjJCA=="

и наоборот

// uri to Base64
b64 = uri.slice(uri.indexOf(',')+1);
// to String
str = atob(b64);
// to Array
arr = str.split('').map(function (e) {return e.charCodeAt(0);});
// to Uint8ClampedArray
u = new Uint8ClampedArray(arr); // [255, 56, 201, 8]