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

问题描述 投票:0回答:2

red的SharpDx BGRA偏移为16]

(color >> 16) & 255

请参见here

但是在.NET中,red的ARGB偏移也是16:

private const int ARGBRedShift = 16;

请参见hereherehere

我很困惑,对吗?

此(如.NET):

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,是Argb Red,但是对于SharpDx,这是Bgra Red。什么是对的?

c# .net colors sharpdx argb
2个回答
0
投票

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

这取决于您要在哪里使用int。但是对于您提供的两个示例,您将以完全相同的方式将字节值打包为整数值。他们都是“正确的”。只是名称不同而已,同一事物可以有许多不同的名称。

长版…

从您注意到的两个源代码参考中可以看到,实际格式为identical。也就是说,每个API的格式都以相同的顺序在每个32位整数中存储每个颜色分量的字节值:蓝色的最低8位,然后是绿色,红色,最高8位为alpha。 。

问题是,对于[[naming]]这样的格式没有统一的标准。在.NET的上下文中,它们按大端顺序列出颜色成分(这可能有点讽刺意味,因为很多Windows生态系统都基于小端顺序硬件,但请参阅下文)。即最重要的字节排在最前面:“ ARGB”。我将此名称称为“ big-endian顺序”,只是因为该名称与一种以big-endian模式运行的计算机上的内存中以4字节的顺序存储32位整数的情况相一致。名称中组件缩写的顺序与在该上下文中出现的顺序相同。另一方面,在SharpDx的上下文中,名称与您在little-endian硬件上看到的字节顺序一致。蓝色字节将首先出现在内存中,然后是绿色,红色,最后是字母。

事实是,这两者都是任意的。虽然现在大多数主流PC都在低端模式下运行,这可能会支持SharpDx命名方案(该格式继承自DirectX环境),但这些API都可以在大端硬件上找到,尤其是.NET Core越来越受欢迎。而且在很多情况下,使用API​​的程序员甚至都不在乎字节的顺序。对于必须处理单个字节的代码,这仍然很重要,但是很多时候,更多的是知道正在使用的工具使用哪种格式写入位图,然后确保已为API指定了正确的格式。

所有这些,我怀疑差异的主要原因与大端与小端无关,而更多与负责API的人员之间的基本哲学差异有关。事实是,即使在big-endian硬件上,像素(其组件以BGRA顺序显示在内存中)的SharpDx格式也将是

“ BGRA”

。因为位图格式不会因为硬件的字节顺序模式不同而改变。像素是not整数。这只是一个字节序列。所不同的是,移位值将必须不同,即取反,以便对于确实将像素视为单个32位整数的代码,它可以正确访问各个组件。相反,在我看来,.NET设计人员已经认识到,其API的用户大部分时间将使用较高级别的颜色(例如,设置笔或画笔的颜色),而不是像素级别的颜色。位图,因此按照常规顺序命名像素格式更有意义。另一方面,在SharpDx中,人们处理低级像素数据的频率更高,在这种情况下,具有能反映像素的实际字节顺序的名称的名称更为合理。

实际上,您所引用的.NET代码不涉及位图数据。关于

“ ARGB”

命名法,Color结构一次只能处理单个int值。从概念上讲,我们想象数字采用大端数字格式(即使是十进制,即最重要的数字在前),因此ARGB更具可读性。另一方面,在.NET涉及像素格式的字节顺序的区域中,您会发现命名可以追溯到代表实际的字节顺序,例如WPF引入的PixelFormats列表。
清澈见底吧? :)

-1
投票
PixelFormats
© www.soinside.com 2019 - 2024. All rights reserved.