为啥将 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*