我有一个十六进制RGB值的二维矩阵,代表一个图像。理想情况下,我想在其上调用类似“putImageData”的函数在画布上绘制图像。但是,它的格式不正确。
在HTML5 Canvas上将矩阵显示为图像的最佳方法是什么?
答案 0 :(得分:1)
无论原始源数据的格式是什么,都必须转换为与canvas兼容的位图格式。
幸运的是,只有一种格式,即使用8位值的RGBA格式。
所以说你的源包含3个字节RGB,你只需将每个像素映射到画布的格式。
要设置位图,您可以使用Uint8Array并使用源矩阵的宽度和高度计算其大小,然后乘以4(RGBA):
var bitmap = new Uint8ArrayClampedArray(width * height * 4);
您也可以根据您想要打包像素数据的方式使用Uint32Array,在这种情况下只使用宽度和高度:
var bitmap = new Uint32Array(width * height);
然后将其缓冲区设置为夹紧视图。
但是如果我们为了简单起见坚持使用前者并假设(因为你不告诉我们)源是RGB(和8:8:8位),你会这样做:
var srcBmp = ??, width = ??, height = ??;
var dstBmp = new Uint8ArrayClampedArray(width * height * 4);
var ptrSrc = 0; // source pointer
var ptrDst = 0; // destination pointer
var dstLen = dstBmp.length;
while(ptrDst < dstLen) {
dstBmp[ptrDst++] = dstBmp[ptrSrc++]; // copy R
dstBmp[ptrDst++] = dstBmp[ptrSrc++]; // copy G
dstBmp[ptrDst++] = dstBmp[ptrSrc++]; // copy B
dstBmp[ptrDst++] = 255; // set alpha to opaque
}
// finally create a ImageData object using the typed array:
var idata = new ImageData(dstBmp, width, height);
ctx.putImageData(idata, x, y); // set x and y
如果您的格式是反向的(例如BMP文件通常就是这种情况),您可以这样做,但仍假设只有RGB:
while(ptrDst < dstLen) {
dstBmp[ptrDst++] = dstBmp[ptrSrc+2]; // copy R from BGR
dstBmp[ptrDst++] = dstBmp[ptrSrc+1]; // copy G
dstBmp[ptrDst++] = dstBmp[ptrSrc ]; // copy B
dstBmp[ptrDst++] = 255; // set alpha to opaque
ptrSrc += 3; // skip to next source pixel
}
对于16位值或浮点,您首先将组件值转换为8位整数[0,255]。如果您使用BMP等格式以及其他特殊情况,则只有步幅处理的情况,但由于没有相关信息,我将把答案保留为通用答案。
等等。它只需要找到像素格式的映射并提取每个组件,然后将其插入到画布的目标位图。