26

我的应用程序的一部分包括使用标准 2d 上下文画布和 webGL 混合的 html5 照片编辑。

无论如何,当用户操作他们的照片时,我正在保存“撤消”状态。这些都作为 base64 图像数据存储在 Javascript 对象中。

一切正常,性能良好。

但是我想知道从 getImageData 存储数据是否会占用更少的内存或提供更好的性能?

所以总结一下我的问题是:

哪个在内存中占用更多空间,由 toDataURL() 生成的 base64 jpeg 还是 getImageData() 的结果?两者之间是否存在任何性能差异(关于加载到画布上,以及从画布中提取数据)

提前致谢。

4

3 回答 3

28

getImageData() 比 toDataURL() 占用更多内存

  • ImageData为像素数组,图像的最大信息,像素数组的长度为widthOfImage * heightOfImage * 4,例如 100 维图像的 imageData 长度为var imageDataArrayLenth = 100 * 100 * 4 = 40 000 (bytes);
  • BLOB(JPG 或 PNG)是使用 jpg 或 png 算法压缩的 imageData,其大小可以比 imageData 小 10 或 20 倍(取决于图像内容)。
  • DataURL(BASE64)是将imageData压缩成JPG或PNG,然后转成字符串,这个字符串比BLOB大37%( info )。

结论:更好的方法是使用BLOB ( info )。

//Example of using blob with objectURL
var canvas = document.getElementById("canvas");

canvas.toBlob((blob) => {
  let img = new Image();
  img.onload = () =>  URL.revokeObjectURL(img.src);  // no longer need to read the blob so it's revoked
  img.src = URL.createObjectURL(blob);
  document.body.appendChild(img);
});
于 2016-01-21T13:07:19.813 回答
12

好问题!我不确定对象本身的真实大小,它应该在 JS 的实现之间有所不同,但这并不意味着我们不能做出一些有根据的猜测。

首先我们可以使用这个问题的近似函数:JavaScript object size

并举个例子:http: //jsfiddle.net/g39uz/

与 ImageData 的 720056 字节相比,该字符串可能是 80116 字节。或者差不多。

这里有一个数量级的差异,如果图像很简单,差异会更加明显。值得记住的是,Base64 表示可以被压缩(确实如此)。让我们通过使用空白画布将其发挥到极致:

http://jsfiddle.net/g39uz/2/

在空白画布上,dataURL 字符串只有 1996 个字节(或大约),但图像数据仍然是 720056,它当然仍然尽职尽责地描述了艰苦的数组细节中的每个像素。

简而言之,如果您要存储它,base64 字符串可能会占用更少的空间。一个数量级。

于 2012-08-10T14:45:40.710 回答
1

前几天我刚刚经历了这个...... getImageData 方法返回一个图像对象,其中实际数据存储在一个 uint8array 中......你必须将数据转换为你的数据库可以管理的东西,它只是不值得,最终输出远大于 toDataURL 方法

将 toDataURL base64 字符串返回到画布上也非常简单......您只需实例化一个新图像并为 src 提供 base64 字符串

于 2012-08-10T14:50:19.533 回答