如何将ARGB唯一打包为一个整数?

发布于 2024-12-03 20:31:37 字数 203 浏览 2 评论 0原文

我有 ARGB 颜色图的四个整数值 (0 - 255)。

现在我想用这四个整数创建一个唯一的浮点数或整数。可以像下面那样做吗?

sum  = 4 * 255 + A;
sum += 3 * 255 + R;
sum += 2 * 255 + G;
sum += 1 * 255 + B;

价值真的独一无二吗?

I have four integer values (0 - 255) for an ARGB color map.

Now I want to make a unique float or integer of these four integers. Is it possible to do it like the following?

sum  = 4 * 255 + A;
sum += 3 * 255 + R;
sum += 2 * 255 + G;
sum += 1 * 255 + B;

Is the value really unique?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

离去的眼神 2024-12-10 20:31:37

您正在尝试进行基本转换或类似的操作。无论如何,逻辑就像基数转换一样。
4 字节 = 32 位。所以 32 位无符号整数就可以了。

在这种情况下,你有:

ARGB = A<<24 + R<<16 + G<<8 + B

就像这样:
你有 4 个字节的数据,这意味着

xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx

X 是 1 或 0 值位。你可以像这样映射它们:

AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB

然后你所要做的就是添加它们,但在此之前你需要移动这些位。将 A 位向左移动 8*3(超出 RGB< /code> 位),然后将 R 位移位 8*2,依此类推。

您最终将这些 32 位整数相加:

AAAAAAAA 00000000 00000000 00000000
00000000 RRRRRRRR 00000000 00000000
00000000 00000000 GGGGGGGG 00000000
00000000 00000000 00000000 BBBBBBBB

其中 ARGB 可以是 01,整体表示通道的8位值。然后您只需将它们相加即可获得结果。或者如 DarkDust 所写,不要使用 + 运算符,而是使用 |< /code> (按位或)运算符,因为在这种特殊情况下它应该更快。

You are trying to do a base convert or something of that sort. Anyway the logic is like in base converting.
4 bytes = 32 bit. So 32 bit unsigned integer would do well.

In this case, you have:

ARGB = A<<24 + R<<16 + G<<8 + B

it's like this:
you have 4 bytes of data, meaning

xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx

where X is either 1 or 0 valued bit. You map them like this:

AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB

and then all you have to do is to add them, but before that you shift the bits. You shift the A bits to the left, by 8*3 (to be beyond the limits of R, G and B bits), then shift the R bits by 8*2, and so on.

You end up adding these 32 bit integers:

AAAAAAAA 00000000 00000000 00000000
00000000 RRRRRRRR 00000000 00000000
00000000 00000000 GGGGGGGG 00000000
00000000 00000000 00000000 BBBBBBBB

Where A, R, G, B can be either 0 or 1, and represent as a whole, the 8 bit value of the channel. Then you simply add them, and obtain the result. Or as DarkDust wrote, use not the + operator, but instead the | (bitwise or) operator, since it should be faster in this particular case.

流心雨 2024-12-10 20:31:37

您可以这样做:

假设 argbunsigned char 类型/uint8_t

uint32_t color = 0;
color |= a << 24;
color |= r << 16;
color |= g << 8;
color |= b;

或更通用(argb< /code> 是任何整数类型):

uint32_t color = 0;
color |= (a & 255) << 24;
color |= (r & 255) << 16;
color |= (g & 255) << 8;
color |= (b & 255);

这将为每个提供一个唯一的整数ARGB组合。您可以像这样取回值:

a = (color >> 24) & 255;
r = (color >> 16) & 255;
g = (color >> 8) & 255;
b = color & 255;

You could do this:

Assuming a, r, g and b to be of type unsigned char/uint8_t:

uint32_t color = 0;
color |= a << 24;
color |= r << 16;
color |= g << 8;
color |= b;

Or more general (a, r, g and b being of any integer type):

uint32_t color = 0;
color |= (a & 255) << 24;
color |= (r & 255) << 16;
color |= (g & 255) << 8;
color |= (b & 255);

This will give you a unique integer for every ARGB combination. You can get the values back like this:

a = (color >> 24) & 255;
r = (color >> 16) & 255;
g = (color >> 8) & 255;
b = color & 255;
梦亿 2024-12-10 20:31:37

不完全是。您需要使用位移而不是简单的乘法。

颜色图中的每个值都是 8 个字节长,对吗?因此,为了使结果数字唯一,必须将它们全部串在一起,总共 8*4=32 位。看看以下内容:

您想要采取:

AAAAAAAA
RRRRRRRR
GGGGGGGG
BBBBBBBB

并使其看起来像:

AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB

这意味着您必须将以下内容添加在一起:

AAAAAAAA000000000000000000000000
        RRRRRRRR0000000000000000
                GGGGGGGG00000000
                        BBBBBBBB
--------------------------------
AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB

我们通过向左移位来完成此操作。将 A 向左移动 24 位将产生 AAAAAAAA,后跟 24 0 位,就像我们想要的那样。遵循该逻辑,您将需要执行以下操作:

sum = A << 24 + R << 16 + G << 8 + B;

为了说明为什么您的建议(使用乘法)不起作用,您的建议会产生以下二进制数,您可以看到重叠:

255 * 1 = 0011111111
255 * 2 = 0111111110
255 * 3 = 1011111101
255 * 4 = 1111111100

此外,只需添加 A、R、G ,结果数的 B 值将始终是常数。简化上面的数学我们得到:

4 * 255 + A + 3 * 255 + R + 2 * 255 + G + 1 * 255 + B
255 * (4 + 3 + 2 + 1) + A + R + G + B
255 * (10) + A + R + G + B
2550 + A + R + G + B

哎呀。

Not quite. You need to use bit-shifting and not simple multiplication.

Each value in your color map is 8 bytes long, correct? So in order for the resulting number to be unique, it must string them all together, for a total of 8*4=32 bits. Look at the following:

You want to take:

AAAAAAAA
RRRRRRRR
GGGGGGGG
BBBBBBBB

and make it look like:

AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB

This means you have to add the following together:

AAAAAAAA000000000000000000000000
        RRRRRRRR0000000000000000
                GGGGGGGG00000000
                        BBBBBBBB
--------------------------------
AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB

We accomplish this by bit-shifting to the left. Taking A and shifting 24 bits to the left will produce AAAAAAAA followed by 24 0 bits, just like we want. Following that logic, you will want to do:

sum = A << 24 + R << 16 + G << 8 + B;

To illustrate why what you suggest (using multiplication) does not work, what you suggest results in the following binary numbers, which you can see overlap:

255 * 1 = 0011111111
255 * 2 = 0111111110
255 * 3 = 1011111101
255 * 4 = 1111111100

Furthermore, simply adding your A, R, G, B values to the resulting number will always be constant. Simplifying your math above we get:

4 * 255 + A + 3 * 255 + R + 2 * 255 + G + 1 * 255 + B
255 * (4 + 3 + 2 + 1) + A + R + G + B
255 * (10) + A + R + G + B
2550 + A + R + G + B

Oops.

佼人 2024-12-10 20:31:37
#include<bitset>
void printBits(string s, int x)
{
    bitset <64> b(x);
    cout<<"\n"<<s<< " " << b;
}
long RGB(int a, int r, int g, int b)
{
    printBits("alpha    ", a);
    printBits("red      ", r);
    printBits("green    ", g);
    printBits("blue     ", b);

    long l = 0;

    l |= a << 24;
    l |= r << 16;
    l |= g << 8;
    l |= b;

    printBits("packed ARGB", l);

    return l;
}
#include<bitset>
void printBits(string s, int x)
{
    bitset <64> b(x);
    cout<<"\n"<<s<< " " << b;
}
long RGB(int a, int r, int g, int b)
{
    printBits("alpha    ", a);
    printBits("red      ", r);
    printBits("green    ", g);
    printBits("blue     ", b);

    long l = 0;

    l |= a << 24;
    l |= r << 16;
    l |= g << 8;
    l |= b;

    printBits("packed ARGB", l);

    return l;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文