代码之家  ›  专栏  ›  技术社区  ›  google dev

将BGRA和ABGR颜色打包为int的正确方法

  •  0
  • google dev  · 技术社区  · 5 年前

    red is 16:

    (color >> 16) & 255

    看见 here

    但是在.NET中,ARGB 红色

    private const int ARGBRedShift = 16;

    here here here .

    我很困惑,什么是对的?

    public int PackeColorToArgb()
    {
        int value = B;
        value |= G << 8;
        value |= R << 16;
        value |= A << 24;
    
        return (int)value;
    }
    

    或者这个(比如SharpDx):

    public int PackeColorToArgb()
    {
        int value = A;
        value |= B << 8;
        value |= G << 16;
        value |= R << 24;
    
        return (int)value;
    }
    

    对于.Net 0xFFFF0000 Red 红色

    0 回复  |  直到 5 年前
        1
  •  1
  •   Peter Duniho    5 年前

    这取决于你要在哪里使用 int

    重要的是,您的第二个代码示例(SharpDx应该是“正确的”)是

    您的第二个代码示例应该与第一个类似。

    长版本…

    从您注意到的两个源代码引用中可以看到,实际格式是 完全相同的 . 也就是说,来自每个API的格式以相同的顺序存储每个颜色组件的字节值,在一个32位整数中:最低8位的是蓝色,然后是绿色,然后是红色,最后是最高8位的alpha。

    问题是,没有统一的标准 这样的格式。在.NET的上下文中,他们按大端顺序列出了颜色组件(这可能被认为有点讽刺,因为Windows生态系统的很多部分都是基于大端硬件的……但是,请参见下文)。一、 e.最重要的字节列在第一位: “ARGB” . 我把这个名字叫做“big endian order”,只是因为这个名字和一个场景是一致的,在这个场景中,一台以big endian模式运行的计算机在内存中以4字节的顺序存储32位整数。名称中组件首字母的顺序与它们在该上下文中出现的顺序相同。

    另一方面,在SharpDx的上下文中,名称与您在little endian硬件上看到的字节顺序一致。蓝色字节首先出现在内存中,然后是绿色、红色,最后是alpha。

    事实上,这两个都有些武断。虽然现在大多数主流PC都在little-endian模式下运行,这可能会支持SharpDx命名方案(从DirectX环境继承而来),但这些API也可以在big-endian硬件上找到,尤其是.NET Core越来越受欢迎。在很多情况下,使用API的程序员甚至不关心字节的顺序。对于必须处理单个字节的代码来说,这仍然很重要,但很多时候,它更重要的是要知道您正在使用的工具是以什么格式编写位图的,然后确保您为API指定了正确的格式。

    “BGRA” 一个整数。它只是一个字节序列。不同的是,移位值必须不同,即反转,以便对于将像素视为单个32位整数的代码,它可以正确地访问各个组件。

    相反,在我看来,.NET设计人员认识到,他们的API的用户大多数时候都是在高级别处理颜色(例如设置笔或画笔的颜色),而不是在位图的像素级别,因此根据常规顺序命名像素格式更有意义。另一方面,在SharpDx中,人们处理低级像素数据的频率要高得多,而拥有一个能够反映像素组件的实际字节顺序的名称在这种情况下更有意义。

    实际上,您引用的.NET代码不涉及位图数据。这个 Color struct只处理单个 一次的值,相对于 “ARGB” 命名法。因为从概念上讲,我们设想数字采用大端格式(即使是十进制格式,也就是先用最重要的数字),所以ARGB更易于人类阅读。另一方面,在.NET中涉及像素格式字节顺序的区域中,您会发现命名回到实际字节顺序的代表,例如 PixelFormats 采用WPF。

    像泥一样干净,对吧?:)