Javascript 如何从JPG的arrayBuffer表示创建画布imageData数组

Javascript 如何从JPG的arrayBuffer表示创建画布imageData数组,javascript,canvas,bytearray,filereader,Javascript,Canvas,Bytearray,Filereader,首先,我知道有一些实现这一点的标准方法(readAsDataURL和drawImage),但不幸的是,它们不适用于这个特定的用例 我正在使用filereader API作为arraybuffer读取图像,如下所示: var reader = new fileReader(); reader.onload = function(e){ var byteArray = new Uint8ClampedArray(e.target.result);

首先,我知道有一些实现这一点的标准方法(readAsDataURL和drawImage),但不幸的是,它们不适用于这个特定的用例

我正在使用filereader API作为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);
var byteArray=new-Uint8ClampedArray(如target.result);
var imgdata=ctx.createImageData(img.width,img.height);
var canvdata=imgdata.data;
对于(变量i=0;i
使用此方法,尽管数据被绘制到画布上,但它看起来像是乱七八糟的雪或噪声,并且不是图像的正确表示形式

这让我相信我在循环中构建的imagedata不正确,或者我获取像素阵列的初始方法不正确

总而言之,我希望能够获取通过html5 fileReader API检索到的arraybuffer(jpeg格式),然后创建一个与画布兼容的imageData数组,以便以后可以使用
putImageData

提前感谢。

编辑

JPEG文件不是简单的颜色数据字节数组,因此不能像这样简单地加载它。如果你不想直接导入画布,你就必须使用JPEG解码库,比如我通过快速谷歌搜索找到的

原创

不幸的是,它们不能用于这个特定的用例

为什么它们不可用

// 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]

我省略了原因,因为它需要一个冗长的解释。简言之,Firefox在使用drawImage缩放画布中的多个大型图像时存在一个已确认的错误。e、 g尝试使用drawImage以循环方式将100个1920x1080 JPEG压缩到其原始大小的一半。在浏览器崩溃之前,您将看到内存使用量呈指数级增长,达到3gb左右。即使在删除所有引用时也是如此。尽管垃圾回收器在最终映像完成后减少了内存使用,但在整个过程中并不能保持内存的稳定。相比之下,Chromes的内存使用率保持在一个水平。这是一次尝试,通过在javascript中缩小imagedata的大小来解决这个问题。我唯一的另一个解决方案是在每个图像缩放之间设置3秒的超时,以允许垃圾收集器进行清理。不幸的是,这不是一个可接受的等待时间。问题是JPEG文件很少包含像素阵列-它是压缩的。您可以将其加载到画布中,并让浏览器的JPEG库对其进行解码,然后将逐像素数据复制到阵列(或第二个画布)中。我明白了,这就解释了问题。不幸的是,按照您的建议操作(将其加载到画布中)会导致内存问题。我真正需要的是一个纯javascript JPEG库,将数据解码为像素数组。谢谢Paul。。。。您的第一个解决方案不幸地导致了同样的问题,似乎Firefox导致了很长时间来释放原始图像数据,即使画布已被清除,所有引用都已消失。实际上,我刚刚找到并尝试了您所指的库,它实际上工作得非常完美!虽然有点慢。希望将此迁移到webworker将有助于保持UI的响应性。如果你想把图书馆的建议变成一个答案,我会把它奖励给你。谢谢