gpt4 book ai didi

javascript - 从 HTML Canvas 中提取的 ArrayBuffer 与使用 UTIF 解码并加载到其上的 ArrayBuffer 不同

转载 作者:行者123 更新时间:2023-12-02 22:29:58 24 4
gpt4 key购买 nike

我的目标是将 TIFF 图像加载到 HTML Canvas 上。前端接收 TIFF 图像的 ArrayBuffer,我能够利用 UTIF 解码 ArrayBuffer 并将其呈现在 HTML Canvas 上。然而,另一个功能要求我导出 Canvas 内容。为此,我再次使用 UTIF 将其编码回 ArrayBuffer,然后将其传递到后端服务器以供使用。

我的功能场景是:

  1. 将 TIFF 图像加载到 Canvas 上。
  2. 在 Canvas 上添加其他对象。例如。圆形、笔划、三 Angular 形等(在下面的代码中被忽略)
  3. 将 Canvas 内容导出为 TIFF 图像。

添加ArrayBuffer的代码:

private _addArrayBufferAsImageOnCanvas(buffer: ArrayBuffer, meta?: {}) {
console.log(buffer); // 8 MB input
// Using UTIF.js to decode the array buffer and convert it to ImageData
const ifds = UTIF.decode(buffer);
const timage = ifds[0];
UTIF.decodeImage(buffer, timage);
const array = new Uint8ClampedArray(UTIF.toRGBA8(timage));
// Forming image Data
const imageData = new ImageData(array, timage.width, timage.height);
// a temporary canvas element
const canvas = document.createElement('canvas');
canvas.width = timage.width;
canvas.height = timage.height;
// on which we draw the ImageData
const ctx = canvas.getContext('2d');
ctx.putImageData(imageData, 0, 0);
// Get the image data
const outImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
// and use UTIF to encode the image
const binaryTiffImage = UTIF.encodeImage(outImageData.data, outImageData.width, outImageData.height);
// output
console.log(binaryTiffImage); // 16 MB output
}

作为输入参数的buffer的大小/字节长度是从 Canvas 中提取的binaryTiffImage的大小/字节长度的一半。 (8MB 输入,16MB 输出)

是不是因为UTIF编码没有压缩数组? (https://github.com/photopea/UTIF.js/blob/master/README.md#utifencodeimagergba-w-h-metadata)

有没有办法可以从 Canvas 中获取与加载时完全相同的 ArrayBuffer?

最佳答案

对于比输入大两倍的输出,是的,压缩可能是最大的问题。

但是,无论如何,即使压缩图像数据,也无法从您正在执行的操作中获取完全相同的文件。

首先,压缩器需要使用与最初使用的完全相同的设置,这可能可行,也可能不可能,但无论如何都不简单。

然后,您将丢失原始 TIFF 文件中的所有元数据。您的进程仅提取原始位图数据,但可以嵌入此 TIFF 中的所有信息(EXIF、jpeg 预览等)都会丢失。

不仅元数据丢失,而且颜色配置文件和颜色深度也丢失,您的代码将 TIFF 中最初的所有内容转换为 sRGB、@32Bits(24 位 + alpha)。

如果您的图像数据使用像 JPEG 这样的松散压缩(虽然很少见,但有可能),那么您可以通过将聚合数据转换为现在的单个像素来创建新数据。

<小时/>

但即使您使用未压缩的原始像素数据@32位,已经具有sRGB颜色配置文件并且能够放回所有原始元数据,您仍然会面临一个大问题:

2D canvas API 很松散:

const ctx = document.createElement('canvas').getContext('2d');
ctx.canvas.width = ctx.canvas.height = 50;

const input = new Uint8ClampedArray(50 * 50 * 4);
crypto.getRandomValues(input); // fill with noise

const input_img = new ImageData( input, 50, 50 );
ctx.putImageData(input_img, 0, 0);
const output = ctx.getImageData(0, 0, 50, 50).data;

const are_different = input.some( (input_value, index) => output[ index ] !== input_value );

console.log( 'input and output are', are_different ? 'different' : 'same' );
// check from your browser's dev-tools
console.table( [input, output] );

公平地说,由于这是由于 alpha 预乘造成的,如果您只有完全不透明的像素,则不会发生这种情况,但所有这些点只会相加。

关于javascript - 从 HTML Canvas 中提取的 ArrayBuffer 与使用 UTIF 解码并加载到其上的 ArrayBuffer 不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58943864/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com