Canvas getImageData转换为RGB值

4

目前我正在进行以下操作:

通过canvas使用getImageData函数获取一个50x50像素的区域的像素数据。

var imageData = ctx.getImageData(0,0,50,50)

我想做的是将这些数据发送给FFMPEG,以便组合成视频。对于RGB24,FFMPEG期望以下内容:

AV_PIX_FMT_RGB24,     ///< packed RGB 8:8:8, 24bpp, RGBRGB...

现在的问题是,我该如何以这种格式获取我的ImageData,以便将其输入到FFMPEG中?
2个回答

0

请查看此处的getImageData文档

使用getImageData方法会返回一个包含大量数组的ImageData对象。对于每个像素,数组中都有四个条目:rgbalpha。因此,该数组看起来像是这样的:[pixel1R,pixel1G,pixel1B,pixel1Alpha,...,pixelNR,pixelNG,pixelNB,pixelNAlpha]

首先,我们需要将所有内容转换为RGB格式。

dataArray = imageData.data
rgbArray = []
for (var i = 0; i < dataArray.length; i+=4) {
    rgbArray.push([dataArray[i], dataArray[i+1], dataArray[i+2]])
}

现在所有内容都已经很好地存储在rgbArray中。
我不是100%确定RGB24,但我相当确定它意味着每个实体有24位,这意味着每个R / G / B各自具有一个字节,这很好,因为这已经是值的范围。现在我们只需要将它们打包。
rgb24Array = rgbArray.map(function(rgbList){
    return (rgbList[0] << 16) | (rgbList[1] << 8) | (rgbList[2])
})

这段代码将红色值向左移动两个字节,绿色值向左移动一个字节,然后将值在一起。

我相当确定这应该能够工作。


之前能够测试它,我得到像11261927这样的值,这就是rgb值。但有些不对劲,首先1只有8位数字而不是9位,其次我似乎找不到任何合理的解释来解释它(在那个位置上)为什么是9。 - nameless
这是因为并非每个RGB值都有3个数字... 所以移位也是错误的... - nameless
我非常确定它应该可以工作。黑色应该产生一个值为0,_纯粹的_绿色(0, 255, 0)应该产生一个值为65280,浅蓝色是非常主观的,所以我无法确定它应该是什么值。 - mjkaufer
如果您执行以下操作,则速度会更快,内存使用量会更少:var b24Bit = new Uint32Buffer(imageData.data.buffer); var i=0; while(i < b24Bit.length) { b24Bit[i++] &= 0xFFFFFF } - Blindman67
@mjkaufer 发现了一件事:http://kylecordes.com/2007/pipe-ffmpeg 在这里你可以看到,ffmpeg似乎不接受纯RGB数据(即使选项可用,也不知道是否真的如此),但是 - 你知道如何将其转换为YUV420而不是RGB吗? - nameless
显示剩余7条评论

0
嗯,看起来你需要一个扁平的字节数组。
Javascript并不支持24位的字,所以你需要将它转换为一个字节数组,并且跳过Alpha通道。
const rgb24 = new Uint8Array((imageData.data.length / 4) * 3);
var i = 0;
var j = 0;
while( i < imageData.data.length){
    rgb24[j++] = imageData.data[i++];
    rgb24[j++] = imageData.data[i++];
    rgb24[j++] = imageData.data[i++];
    i++;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接