.NET颜色中的RGB格式 [英] RGB formats in .NET Color

查看:82
本文介绍了.NET颜色中的RGB格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



如果在此处看到,它将根据设置颜色RGB的8位值。换句话说,这是我假设的RGB-888格式...我想。



我在相机中使用的是RGB-565格式(R为5位,B和G的6)
是否可以将Color设置为基于这种格式而不是888的颜色?
还是我自己必须手动执行此操作?

解决方案

我最近编写了代码来做到这一点,基于在 ScummVM项目的通用颜色格式转换器上。



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



使用10位深度的数字图像



请记住,我不确定每个乘数的确切值factor适用于5-6-5格式。 6位分量仅仅是更准确吗?在这种情况下,自动转换系统将完成任务。



无论如何,使用上面链接的代码,此示例应完全适合您的需求。在这里,它用于转换自定义5-5-5-1 RGBA格式:

  // bytes 84 21 ==> ; 0x8421(BE)== bin ==> 1000 0100 0010 0001 ==分割== 10000 10000 10000 1 == dec ==> 16 16 16 1(RGBA)==调整== 128 128 128 255 
//构造函数中的值是:每个像素的字节数,位数和为获取R,G,B和A分量而要移位的数量,以及数据字节序。
私有静态PixelFormatter SixteenBppFormatter = new PixelFormatter(2,5,11,5,6,5,1,1,0,false);

受保护的静态Byte [] Convert16bTo32b(Byte [] imageData,Int32 startOffset,Int32 width,Int32 height,ref Int32 stride)
{
Int32 newImageStride = width * 4; ;
Byte [] newImageData =新的Byte [height * newImageStride];
for(Int32 y = 0; y< height; y ++)
{
for(Int32 x = 0; x< width; x ++)
{
Int32 sourceOffset = y *步幅+ x * 2;
Int32 targetOffset = y * newImageStride + x * 4;
颜色c = SixteenBppFormatter.GetColor(imageData,startOffset + sourceOffset);
PixelFormatter.Format32BitArgb.WriteColor(newImageData,targetOffset,c);
}
}
stride = newImageStride;
返回newImageData;
}

您需要做的就是定义自己的PixelFormatter,并为其分配正确的位5-6-5格式。



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

  ///< summary> 
///从图像获取原始字节。
///< / summary>
///< param name = sourceImage>要从中获取字节的图像。< / param>
///< param name = stride>所检索图像数据的跨度。
///< returns>图片的原始字节< / returns>
公共静态字节[] GetImageData(位图sourceImage,超出Int32步长)
{
BitmapData sourceData = sourceImage.LockBits(new Rectangle(0,0,sourceImage.Width,sourceImage.Height), ImageLockMode.ReadOnly,sourceImage.PixelFormat);
步幅= sourceData.Stride;
Byte [] data = new Byte [stride * sourceImage.Height];
Marshal.Copy(sourceData.Scan0,data,0,data.Length);
sourceImage.UnlockBits(sourceData);
个返回数据;
}

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



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

I have been checking the documentation on Color (I am writing a C# program) Setting a color to Color

If you see there, it sets a color based on 8-bit values of RGB. In other words, this is I suppose a RGB-888 format...I guess.

I am using in my camera a RGB-565 format (5 bits for R,B and 6 for G) Is there a way to set Color to a color based on this format and not 888? Or do I have to do this manually myself?

解决方案

I have recently written code to do exactly that, based on the generic colour format converter of the ScummVM project.

The answer is on a different question here on StackOverflow, and although the question isn't really a duplicate, I think, the answer is, so I'll just link to it:

Working with 10 bits depth digital image

Mind you, I'm not sure exactly how the multiplier for each factor works on the 5-6-5 format. Is the 6-bit component simply more accurate? In that case, the automated conversion system will do the job.

Anyway, with the code linked above, this example should suit your needs perfectly. Here it is used to convert a custom 5-5-5-1 RGBA format:

//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;
}

All you need to do is define your own PixelFormatter with the correct bits distribution for the 5-6-5 format.

You will indeed need to look into Bitmap.LockBits() to get the original 16-bit data out of the image, and to write that data into a new 32-bit ARGB image. My BuildImage function mentioned in this answer should show how to handle the writing. The read method is actually a lot simpler:

/// <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;
}

Do note, in all situations where you edit raw image bytes, the difference between "stride" and "width". In a lot of formats, one line of pixels in an image is padded to the next multiple of four bytes, so you can't just read and process it as array assuming it's all image data; those padding bytes will mess that up really quickly. As shown in my example code to convert my 16bpp format to ARGB, you really need to do that line by line, and per line make sure you only use the data that is still within the (width * bytes per pixel) range.

I've noticed that for all functions that may change the stride, it's advised to give it as ref parameter.

这篇关于.NET颜色中的RGB格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆