Sag*_*gor 9 javascript base64 canvas image
我有名为 frameBytes 的 Uint8Array。我已经用这段代码从这个字节数组中创建了 RGBA 值。
for (var i = 0; i < frameBytes.length; i++) {
imgData.data[4 * i] = frameBytes[i];// red
imgData.data[4 * i + 1] = frameBytes[i]; // green
imgData.data[4 * i + 2] = frameBytes[i];// blue
imgData.data[4 * i + 3] = 255; // alpha
}
Run Code Online (Sandbox Code Playgroud)
然后我使用以下代码将此 GRBA 值显示到画布上。
var ctx = fingerFrame.getContext('2d');
var imgData = ctx.createImageData(fingerFrame.width, fingerFrame.height);
ctx.putImageData(imgData, 0, 0, 0, 0, fingerFrame.width, fingerFrame.height);
Run Code Online (Sandbox Code Playgroud)
在那之后,我曾经使用以下代码在画布中对图像标记进行图像处理:
const img = document.getElementById('i');
img.src = fingerFrame.toDataURL();
Run Code Online (Sandbox Code Playgroud)
但我不想使用画布。我想直接在 Uint8Array 的图像标签中显示图像。我怎样才能做到这一点?任何帮助将不胜感激。
我想直接在 Uint8Array 的图像标签中显示图像
使用 Blob 非常简单:
// Small red dot image
const content = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 5, 0, 0, 0, 5, 8, 6, 0, 0, 0, 141, 111, 38, 229, 0, 0, 0, 28, 73, 68, 65, 84, 8, 215, 99, 248, 255, 255, 63, 195, 127, 6, 32, 5, 195, 32, 18, 132, 208, 49, 241, 130, 88, 205, 4, 0, 14, 245, 53, 203, 209, 142, 14, 31, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130]);
document.getElementById('my-img').src = URL.createObjectURL(
new Blob([content.buffer], { type: 'image/png' } /* (1) */)
);Run Code Online (Sandbox Code Playgroud)
Should display a small red dot: <img id="my-img">Run Code Online (Sandbox Code Playgroud)
(1) 它也可以在不指定 Blob MIME 类型的情况下工作。
ImageData我认为你可以直接从该页面上的示例中创建一个:
const arr = new Uint8ClampedArray(40000);
// Iterate through every pixel
for (let i = 0; i < arr.length; i += 4) {
arr[i + 0] = 0; // R value
arr[i + 1] = 190; // G value
arr[i + 2] = 0; // B value
arr[i + 3] = 255; // A value
}
// Initialize a new ImageData object
let imageData = new ImageData(arr, 200);
Run Code Online (Sandbox Code Playgroud)
不幸的是,似乎没有任何方法可以ImageData在<img>元素中显示 an ,只能在 a 中显示<canvas>。<img>需要一个实际的图像文件。
幸运的是,BMP 格式得到了广泛的支持,并且支持原始 RGBA 数据。您只需添加适当的 BMP 标头即可。完成后,您可以<img>使用 Ben Fortune 概述的技术将数据传递给系统。我不会使用data:,即使你发现整个网络上都有人使用它。这是不必要的低效。
这是一些示例代码。它将像素数据附加到单个缓冲区中的位图标头,因为这样会更有效。如果您已经拥有数据,您可以Uint8Array为标题创建一个单独的数据,然后在Blob构造函数中将它们连接起来,即new Blob([header, pixels]). 我没试过。
const arr = new Uint8ClampedArray(40000);
// Iterate through every pixel
for (let i = 0; i < arr.length; i += 4) {
arr[i + 0] = 0; // R value
arr[i + 1] = 190; // G value
arr[i + 2] = 0; // B value
arr[i + 3] = 255; // A value
}
// Initialize a new ImageData object
let imageData = new ImageData(arr, 200);
Run Code Online (Sandbox Code Playgroud)
const header_size = 70;
const width = 255;
const height = 255;
const image_size = width * height * 4;
const arr = new Uint8Array(header_size + image_size);
const view = new DataView(arr.buffer);
// File Header
// BM magic number.
view.setUint16(0, 0x424D, false);
// File size.
view.setUint32(2, arr.length, true);
// Offset to image data.
view.setUint32(10, header_size, true);
// BITMAPINFOHEADER
// Size of BITMAPINFOHEADER
view.setUint32(14, 40, true);
// Width
view.setInt32(18, width, true);
// Height (signed because negative values flip
// the image vertically).
view.setInt32(22, height, true);
// Number of colour planes (colours stored as
// separate images; must be 1).
view.setUint16(26, 1, true);
// Bits per pixel.
view.setUint16(28, 32, true);
// Compression method, 6 = BI_ALPHABITFIELDS
view.setUint32(30, 6, true);
// Image size in bytes.
view.setUint32(34, image_size, true);
// Horizontal resolution, pixels per metre.
// This will be unused in this situation.
view.setInt32(38, 10000, true);
// Vertical resolution, pixels per metre.
view.setInt32(42, 10000, true);
// Number of colours. 0 = all
view.setUint32(46, 0, true);
// Number of important colours. 0 = all
view.setUint32(50, 0, true);
// Colour table. Because we used BI_ALPHABITFIELDS
// this specifies the R, G, B and A bitmasks.
// Red
view.setUint32(54, 0x000000FF, true);
// Green
view.setUint32(58, 0x0000FF00, true);
// Blue
view.setUint32(62, 0x00FF0000, true);
// Alpha
view.setUint32(66, 0xFF000000, true);
// Pixel data.
for (let w = 0; w < width; ++w) {
for (let h = 0; h < height; ++h) {
const offset = header_size + (h * width + w) * 4;
arr[offset + 0] = w; // R value
arr[offset + 1] = h; // G value
arr[offset + 2] = 255-w; // B value
arr[offset + 3] = 255-h; // A value
}
}
const blob = new Blob([arr], { type: "image/bmp" });
const url = window.URL.createObjectURL(blob);
const img = document.getElementById('i');
img.src = url;Run Code Online (Sandbox Code Playgroud)
需要注意的是,这种 BMP 的 RGBA 变体根本没有得到广泛支持。Chrome 似乎支持它。Firefox 没有,Apple 的 finder 也没有。如果你正在编写一个 Electron 应用程序,它应该没问题,但我不会在网络上使用它。
但是,由于您已将 alpha 设置为 255,我猜您甚至不需要 alpha 通道。在这种情况下,您可以改用BI_RGB:
<img id="i">Run Code Online (Sandbox Code Playgroud)
const header_size = 54;
const width = 255;
const height = 255;
const image_size = width * height * 4;
const arr = new Uint8Array(header_size + image_size);
const view = new DataView(arr.buffer);
// File Header
// BM magic number.
view.setUint16(0, 0x424D, false);
// File size.
view.setUint32(2, arr.length, true);
// Offset to image data.
view.setUint32(10, header_size, true);
// BITMAPINFOHEADER
// Size of BITMAPINFOHEADER
view.setUint32(14, 40, true);
// Width
view.setInt32(18, width, true);
// Height (signed because negative values flip
// the image vertically).
view.setInt32(22, height, true);
// Number of colour planes (colours stored as
// separate images; must be 1).
view.setUint16(26, 1, true);
// Bits per pixel.
view.setUint16(28, 32, true);
// Compression method, 0 = BI_RGB
view.setUint32(30, 0, true);
// Image size in bytes.
view.setUint32(34, image_size, true);
// Horizontal resolution, pixels per metre.
// This will be unused in this situation.
view.setInt32(38, 10000, true);
// Vertical resolution, pixels per metre.
view.setInt32(42, 10000, true);
// Number of colours. 0 = all
view.setUint32(46, 0, true);
// Number of important colours. 0 = all
view.setUint32(50, 0, true);
// Pixel data.
for (let w = 0; w < width; ++w) {
for (let h = 0; h < height; ++h) {
const offset = header_size + (h * width + w) * 4;
arr[offset + 0] = w; // R value
arr[offset + 1] = h; // G value
arr[offset + 2] = 255-w; // B value
// arr[offset + 3] is ignored but must still be present because we specified 32 BPP
}
}
const blob = new Blob([arr], { type: "image/bmp" });
const url = window.URL.createObjectURL(blob);
const img = document.getElementById('i');
img.src = url;Run Code Online (Sandbox Code Playgroud)
在上面的示例中我仍然使用 32 BPP,但是因为我将压缩设置为BI_RGBalpha 通道被忽略。这有点浪费内存。您可以将其设置为24 BPP,然后每个像素仅使用 3 个字节,但需要注意的是每行都必须填充到 4 字节的倍数,而我在这里懒得这样做。
Olu*_*aya -3
我相信您可以使用 btoa 函数,它将创建图像数据的 base64 ASCII 表示形式。
const img = document.getElementById('i');
//ImageDataArrayBuffer is your uint8 Array Buffer
img.src = "data:image/png;base64,"+ btoa(String.fromCharCode.apply(null, ImageDataArrayBuffer));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14776 次 |
| 最近记录: |