【问题标题】:How to convert RGB camera image to ARGB format of SharpDX? [closed]如何将 RGB 相机图像转换为 SharpDX 的 ARGB 格式? [关闭]
【发布时间】:2019-08-23 06:43:45
【问题描述】:

我有一张从相机捕获的 RGB 图像(RGB 4:4:4 色彩空间,每像素 24 位)。我使用Gorgon 2D 库(基于 SharpDX 构建)将此图像显示为纹理,因此我必须将其转换为 ARGB。我使用此代码(不是我的代码)将 RGB 相机图像转换为 RGBA。

[StructLayout(LayoutKind.Sequential)]
public struct RGBA
{
            public byte r;
            public byte g;
            public byte b;
            public byte a;
}

[StructLayout(LayoutKind.Sequential)]
public struct RGB
{
            public byte r;
            public byte g;
            public byte b;
}

unsafe void internalCvt(long pixelCount, byte* rgbP, byte* rgbaP)
            {
                for (long i = 0, offsetRgb = 0; i < pixelCount; i += 4, offsetRgb += 12)
                {
                    uint c1 = *(uint*)(rgbP + offsetRgb);
                    uint c2 = *(uint*)(rgbP + offsetRgb + 3);
                    uint c3 = *(uint*)(rgbP + offsetRgb + 6);
                    uint c4 = *(uint*)(rgbP + offsetRgb + 9);
                    ((uint*)rgbaP)[i] = c1 | 0xff000000;
                    ((uint*)rgbaP)[i + 1] = c2 | 0xff000000;
                    ((uint*)rgbaP)[i + 2] = c3 | 0xff000000;
                    ((uint*)rgbaP)[i + 3] = c4 | 0xff000000;
                }
            }

public unsafe void RGB2RGBA(int pixelCount, byte[] rgbData, byte[] rgbaData)
            {
                if ((pixelCount & 3) != 0) throw new ArgumentException();
                fixed (byte* rgbP = &rgbData[0], rgbaP = &rgbaData[0])
                {
                    internalCvt(pixelCount, rgbP, rgbaP);
                }
            }

然后像这样将 RGB 转换为 RGBA:

byte[] rgb = new byte[800*600*3]; //Stored data
byte[] rgba = new byte[800 * 600 * 4];
RGB2RGBA(800*600, rgb, rgba)

并且我使用 rgba 作为 Gorgon 纹理的数据:

unsafe
{
     fixed(void* rgbaPtr = rgba)
     {
          var buff = new GorgonNativeBuffer<byte>(rgbaPtr, 800*600*4);                      
          GorgonImageBuffer imb = new GorgonImageBuffer(buff, 800, 600, BufferFormat.R8G8B8A8_UNorm);

          //Set Texture data  GorgonTexture2D                                
          Texture.SetData(imb, new SharpDX.Rectangle(0, 0, 800, 600), 0, 0, CopyMode.NoOverwrite);
         }
}

但纹理图像的颜色与相机图像的颜色不同。

所以我认为我必须将相机图像转换为 ARGB(不是 RGBA),以便它可以显示为 Gorgon 纹理,但我不知道如何使用上面的代码进行操作。各位大神能指点一下吗?

谢谢!

以下是我在上面代码中使用的 Gorgon 库类型的链接

GorgonTexture2D GorgonNativeBuffer GorgonImageBuffer

【问题讨论】:

  • 只需将A字节设置为0xff ?
  • 你能用system.drawing.color吗?有方法调用 Color.FromArgb() 和 Color.ToArgb()。
  • 你能澄清一下格式吗?例如,这个 RGBA 结构在最低字节中有 R,通常称为 ABGR(因此十六进制的颜色读取 0xAABBGGRR)。 ARGB 通常表示 0xAARRGGBB,即 R 和 B 的位置交换,但 A 的位置相同。不幸的是,存在一些相互冲突的命名约定
  • 由于 RGB 没有 alpha 值,因此不能透明,我们只需将 A 字节设置为其最大值 0xFF,即完全不透明
  • Color argb = Color.FromArgb(255, r, g, b) 应该和 .NET 编码人员一样快。在尝试其他任何事情之前,我会先尝试..

标签: c# rgb argb


【解决方案1】:

目标的字节顺序在内存中为R G B A。源的字节顺序在内存中为B G R。所以除了将每3个字节扩展为4个字节并将FF放入新的A通道之外,R和B通道需要交换位置。例如,

unsafe void internalCvt(long pixelCount, byte* rgbP, uint* rgbaP)
{
    for (long i = 0, offsetRgb = 0; i < pixelCount; i += 4, offsetRgb += 12)
    {
        uint c1 = *(uint*)(rgbP + offsetRgb);
        uint c2 = *(uint*)(rgbP + offsetRgb + 3);
        uint c3 = *(uint*)(rgbP + offsetRgb + 6);
        uint c4 = *(uint*)(rgbP + offsetRgb + 9);
        // swap R and B
        c1 = (c1 << 16) | (c1 & 0xFF00) | ((c1 >> 16) & 0xFF);
        c2 = (c2 << 16) | (c2 & 0xFF00) | ((c2 >> 16) & 0xFF);
        c3 = (c3 << 16) | (c3 & 0xFF00) | ((c3 >> 16) & 0xFF);
        c4 = (c4 << 16) | (c4 & 0xFF00) | ((c4 >> 16) & 0xFF);
        // set alpha to FF
        rgbaP[i] = c1 | 0xff000000;
        rgbaP[i + 1] = c2 | 0xff000000;
        rgbaP[i + 2] = c3 | 0xff000000;
        rgbaP[i + 3] = c4 | 0xff000000;
    }
}

或者更简单的版本,每次迭代处理一个像素并且不使用unsafe

void internalCvt(long pixelCount, byte[] bgr, byte[] rgba)
{
    long byteCount = pixelCount * 4;
    for (long i = 0, offsetBgr = 0; i < byteCount; i += 4, offsetRgb += 3)
    {
        // R
        rgba[i] = bgr[offsetBgr + 2];
        // G
        rgba[i + 1] = bgr[offsetBgr + 1];
        // B
        rgba[i + 2] = bgr[offsetBgr];
        // A
        rgba[i + 3] = 0xFF;
    }
}

【讨论】:

  • 非常感谢,但是转换函数是: public static unsafe void RGB2RGBA_FastConvert4v2(int pixelCount, byte[] rgbData, byte[] rgbaData)) 那么它如何在 RGB2RGBA_FastConvert4v2 函数中调用你的函数rgbaData 是一个字节[]
  • @Dominota 您可以像在原始代码中一样投射指针,我将其移出以便在这方面减少冗余,例如internalCvt(pixelCount, rgbP, (uint*)rgbaP)
  • 天哪!它就像魅力一样。你救了我的命:))@harold。非常感谢!
  • 这是我第一次在 StackOverflow 上提问,得到了大家的帮助。谢谢你们,谢谢 StackOverflow!!!!
  • 在您的invervnalCvt中,当我想将RGBA转换为ARGB时,我不需要交换R和B,只需将alpha设置为FF吗?
猜你喜欢
  • 2021-12-15
  • 2020-02-29
  • 1970-01-01
  • 1970-01-01
  • 2017-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-27
相关资源
最近更新 更多