Как создать массив 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]