繁体   English   中英

.NET Color中的RGB格式

[英]RGB formats in .NET Color

我一直在查看关于Color的文档(我正在编写一个C#程序) 将颜色设置为Color

如果你看到它,它会根据RGB的8位值设置颜色。 换句话说,这是我想的RGB-888格式......我猜。

我在相机中使用的是RGB-565格式(R,B为5位,G为5)有没有办法根据这种格式将颜色设置为颜色而不是888? 或者我必须自己手动完成此操作?

我最近根据ScummVM项目通用颜色格式转换器编写了代码来完成这项工作

答案是关于StackOverflow的另一个问题,虽然这个问题并不是真的重复,但我认为答案是,所以我只是链接到它:

使用10位深度数字图像

请注意,我不确定每个因素的乘数是如何在5-6-5格式上起作用的。 6位组件是否更准确? 在这种情况下,自动转换系统将完成这项工作。

无论如何,通过上面链接的代码,这个例子应该完全符合您的需求。 这里它用于转换自定义5-5-5-1 RGBA格式:

//bytes 84 21 ==> 0x8421 (BE) ==bin==> 1000 0100 0010 0001 ==split==> 10000 10000 10000 1 ==dec==> 16 16 16 1 (RGBA) ==adjust==> 128 128 128 255
// values in constructor are: bytes per pixel, amount of bits and amount to shift for getting R, G, B and A components, and data endianness.
private static PixelFormatter SixteenBppFormatter = new PixelFormatter(2, 5, 11, 5, 6, 5, 1, 1, 0, false);

protected static Byte[] Convert16bTo32b(Byte[] imageData, Int32 startOffset, Int32 width, Int32 height, ref Int32 stride)
{
    Int32 newImageStride = width * 4; ;
    Byte[] newImageData = new Byte[height * newImageStride];
    for (Int32 y = 0; y < height; y++)
    {
        for (Int32 x = 0; x < width; x++)
        {
            Int32 sourceOffset = y * stride + x * 2;
            Int32 targetOffset = y * newImageStride + x * 4;
            Color c = SixteenBppFormatter.GetColor(imageData, startOffset + sourceOffset);
            PixelFormatter.Format32BitArgb.WriteColor(newImageData, targetOffset, c);
        }
    }
    stride = newImageStride;
    return newImageData;
}

您需要做的就是使用5-6-5格式的正确位分配定义您自己的PixelFormatter。

您确实需要调查Bitmap.LockBits()以从图像中获取原始的16位数据,并将该数据写入新的32位ARGB图像。 我在这个答案中提到的BuildImage函数应该显示如何处理写作。 read方法实际上要简单得多:

/// <summary>
/// Gets the raw bytes from an image.
/// </summary>
/// <param name="sourceImage">The image to get the bytes from.</param>
/// <param name="stride">Stride of the retrieved image data.</param>
/// <returns>The raw bytes of the image</returns>
public static Byte[] GetImageData(Bitmap sourceImage, out Int32 stride)
{
    BitmapData sourceData = sourceImage.LockBits(new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), ImageLockMode.ReadOnly, sourceImage.PixelFormat);
    stride = sourceData.Stride;
    Byte[] data = new Byte[stride * sourceImage.Height];
    Marshal.Copy(sourceData.Scan0, data, 0, data.Length);
    sourceImage.UnlockBits(sourceData);
    return data;
}

请注意,在编辑原始图像字节的所有情况下,“stride”和“width”之间的区别。 在许多格式中,图像中的一行像素被填充到下一个四个字节的倍数,所以你不能只是读取并处理它作为数组,假设它是所有的图像数据; 那些填充字节会很快崩溃。 如我的示例代码中所示,将我的16bpp格式转换为ARGB,您确实需要逐行执行此操作,并且每行确保您仅使用仍在(宽度*每像素的字节数)范围内的数据。

我注意到,对于可能改变步幅的所有函数,建议将其作为ref参数给出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM