为啥将 unsigned char 用于 RGB 像素数据?

Posted

技术标签:

【中文标题】为啥将 unsigned char 用于 RGB 像素数据?【英文标题】:why unsigned char for RGB pixel data?为什么将 unsigned char 用于 RGB 像素数据? 【发布时间】:2011-08-10 05:19:00 【问题描述】:

我正在使用一些基本的计算机图形学 C++。

像素数据通常表示为:

unsigned char *pixels

unsigned char 很好,因为它是一个介于 0 和 255 之间的值(256 = 2^8,因为 char 是 2 字节而 1 字节是 8 位?)。这很好,因为在 RGB 中,颜色用 0 到 255 之间的数字表示。

但是.. 我将其理解为单色图像,在正常图像中我有 RGB,我将有 3 个无符号字符数组,一个用于红色,一个用于绿色,一个用于蓝色。类似:

unsigned char *pixels[3]

但我从来没有发现类似的 RGB 像素数据

【问题讨论】:

1 字节为 8 位。位有 2 个状态。所以一个字节,8位,有2^8个状态。因此 1 个字节有 2^8=256 种不同的可能状态。无符号字符是 1 个字节,有 256 个不同的值,从 0 到 255。 【参考方案1】:

使用 *pixels[3] 您可以得到三个颜色分量的单独数组,而在文件中单个像素的三个颜色分量存储在一起。这也意味着您可以对整个图像数据块使用单个 fread()/fwrite(),

【讨论】:

【参考方案2】:
unsigned char *pixels[3];

声明一个由三个指向 unsigned char 的指针组成的数组。我不确定这是否是你想要的。

有几种不同的方式来表示像素。最简单的可能是这样的:

struct Pixel

    unsigned char red;
    unsigned char green;
    unsigned char blue;
;

但您可能必须(或想要)遵守某些外部格式。另一种常见的可能性是将所有三种颜色放在uint32_t 中。此外,在某些图形系统中,可能还有第四个元素和 alpha,表示透明度。

【讨论】:

【参考方案3】:

RGB 图像通常以交错顺序存储(R1、G1、B1、R2、G2、B2、...),因此一个指针(指向 R1)就足够了。

这使得处理单个像素有点困难:索引为 N 的像素存储在pixels[3*N+0]pixels[3*N+1]pixels[3*N+2] 而不仅仅是red[N], green[N], blue[N]

不过,这样做的好处是可以更快地访问:更少的指针导致程序更简单,从而提高了它们的速度;交错的顺序也使内存缓存更有效。

【讨论】:

【参考方案4】:

真的,每当您引用一个字节块时,它的类型都是unsigned char*,因为根据 C 规范,unsigned char 在类型本身中没有填充(即,每个位都用于字节中的一个值,并且没有未使用的填充位),并且像素数据将是一些没有填充的 X 字节块(至少不是内部填充......最后可能有填充用于对齐目的的缓冲区)。它也很可能被分配在堆上的某个地方。因此,无论是单色、彩色数据等,您经常会发现像素缓冲区将通过 unsigned char 指针指向,然后您可以将其转换为 struct,就像 James 提到的以便轻松访问像素信息。其他时候你可能不得不像 anatolyg 提到的那样索引缓冲区。但归根结底,像素缓冲区只是数据缓冲区,一般的数据字节缓冲区应该在 C/C++ 中使用 unsigned char* 类型访问。

【讨论】:

以上是关于为啥将 unsigned char 用于 RGB 像素数据?的主要内容,如果未能解决你的问题,请参考以下文章

数据类型unsigned char表示范围(存储值的范围)是多少,为啥(写出计算过程)

为啥打印 unsigned char 有时有效,有时无效?在 C 中

为啥我不能声明 unsigned char* test = "Some text"

将 unsigned char * 复制到 unsigned char*

C: unsigned char * bytes 数组将元素复制到其他 unsigned char * 数组

如何将 unsigned char[] 转换为 std::vector<unsigned char>