Javascript 将 YUV 转换为 RGB

标签 javascript html canvas rgb yuv

我在 js 中有 YUV 图像字节数组(UINtArray),是否可以将其转换为 rgb?或者如何在 Canvas 上绘制它?

这里是链接,它使用 webGL Canvas ,通过填充纹理/但我需要使用 2D 上下文 Canvas 来做到这一点。我知道它可能会更慢,但无论如何。 https://github.com/mbebenita/Broadway/blob/master/Player/canvas.js

var lumaSize = width * height,
    chromaSize = lumaSize >> 2;
webGLCanvas.YTexture.fill(buffer.subarray(0, lumaSize));
webGLCanvas.UTexture.fill(buffer.subarray(lumaSize, lumaSize + chromaSize));
webGLCanvas.VTexture.fill(buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize));
webGLCanvas.drawScene();

更新:图像YUV字节也是我看到的I420格式

Update2:我在 c++ 中找到了我认为可行的示例,但是你能帮我把它转换成 js 吗?

static int getR(int y, int u, int v)
{
    return clamp(y + (int) (1.402f * (v - 128)));
}

static int getG(int y, int u, int v)
{
    return clamp(y - (int) (0.344f * (u - 128) + 0.714f * (v - 128)));
}

static int getB(int y, int u, int v)
{
    return clamp(y + (int) (1.772f * (u - 128)));
}

static int getY(int r, int g, int b)
{
    return (int) (0.299f * r + 0.587f * g + 0.114f * b);
}

static int getU(int r, int g, int b)
{
    return (int) (-0.169f * r - 0.331f * g + 0.499f * b + 128);
}

static int getV(int r, int g, int b)
{
    return (int) (0.499f * r - 0.418f * g - 0.0813f * b + 128);
}

static int clamp(int value)
{
    return Math::Min(Math::Max(value, 0), 255);
}

static void ConvertI420ToRGB24(SSourcePicture *yuvImage, unsigned char *rgbData)
{
    int yPadding = yuvImage->iStride[0] - yuvImage->iPicWidth;
    int uPadding = yuvImage->iStride[1] - (yuvImage->iPicWidth / 2);
    int vPadding = yuvImage->iStride[2] - (yuvImage->iPicWidth / 2);

    int yi = 0;
    int ui = 0;
    int vi = 0;
    int rgbi = 0;
    for (int ypos = 0; ypos < yuvImage->iPicHeight; ypos++)
    {
        for (int xpos = 0; xpos < yuvImage->iPicWidth; xpos++)
        {
            int y = yuvImage->pData[0][yi] & 0xFF;
            int u = yuvImage->pData[1][ui] & 0xFF;
            int v = yuvImage->pData[2][vi] & 0xFF;

            int r = getR(y, u, v);
            int g = getG(y, u, v);
            int b = getB(y, u, v);

            if (BitConverter::IsLittleEndian)
            {
                rgbData[rgbi++] = (unsigned char) b;
                rgbData[rgbi++] = (unsigned char) g;
                rgbData[rgbi++] = (unsigned char) r;
            }
            else
            {
                rgbData[rgbi++] = (unsigned char) r;
                rgbData[rgbi++] = (unsigned char) g;
                rgbData[rgbi++] = (unsigned char) b;
            }

            yi++;
            if (xpos % 2 == 1)
            {
                ui++;
                vi++;
            }
        }

        yi += yPadding;

        if (ypos % 2 == 0)
        {
            ui -= (yuvImage->iPicWidth / 2);
            vi -= (yuvImage->iPicWidth / 2);
        }
        else
        {
            ui += uPadding;
            vi += vPadding;
        }
    }
}

最佳答案

这里是将 yuv 转换为 rgb 的 JS 代码。

function yuv2rgb(y,u,v){
  y=parseInt(y);
  u=parseInt(u);
  v=parseInt(v);
  r=clamp(Math.floor(y+1.4075*(v-128)),0,255);
  g=clamp(Math.floor(y-0.3455*(u-128)-(0.7169*(v-128))),0,255);
  b=clamp(Math.floor(y+1.7790*(u-128)),0,255);
  return({r:r,g:g,b:b});
}

function clamp(n,low,high){
    if(n<low){return(low);}
    if(n>high){return(high);}
}

您可以使用 var imgData=ctx.createImageData(canvas.width,canvas.height) 创建一个“从头开始”的像素数组,您可以将 rgb 值输入其中。

构建像素阵列后,您可以使用 ctx.putImageData(imgData) 将其绘制到 Canvas 上

关于Javascript 将 YUV 转换为 RGB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21264648/

相关文章:

javascript - 我正在尝试动态更改 div 元素的大小

javascript - 当您单击 Canvas 内的矩形时,其中所有形状都会全屏显示

html - 绝对定位的内容不会显示在 angular ui-router ui-view 中

jquery - 在下拉菜单外呈现的下拉菜单选项

html - 如果我使用#!而不是 anchor 标记 <a> 的 href 中的#?

javascript - 使用js打印canvas.js图表

javascript - 如何为 svg 路径的渐进式绘图设置动画?

javascript - 从 ajax 请求将嵌套数据加载到制表器表

javascript - 使用 Three.js 将一个对象的旋转应用于另一个对象

javascript - Angular ng-change 指令不起作用