C++ 为什么图像像素应该在内存中的字单元中平铺?

C++ 为什么图像像素应该在内存中的字单元中平铺?,c++,image,image-processing,C++,Image,Image Processing,我现在正在阅读的源代码,这是一个伟大的文档图像处理和分析库。在此库中,它包含一个基本图像结构Pix,用于表示图像。在这种结构中,它有一个变量来定义每个图像水平线中像素应该保留多少字(一个字等于4字节),定义如下: wpl = (width * depth + 31) / 32; 其中depth表示一个像素包含多少位。例如,对于灰度图像,其像素深度为8,而对于彩色图像,其像素深度为24 然后,应为图像像素分配的存储器变为: 4 * wpl * height; 对我来说,我无法理解为什么像素

我现在正在阅读的源代码,这是一个伟大的文档图像处理和分析库。在此库中,它包含一个基本图像结构
Pix
,用于表示图像。在这种结构中,它有一个变量来定义每个图像水平线中像素应该保留多少字(一个字等于4字节),定义如下:

 wpl = (width * depth + 31) / 32;
其中
depth
表示一个像素包含多少位。例如,对于灰度图像,其像素深度为8,而对于彩色图像,其像素深度为24

然后,应为图像像素分配的存储器变为:

4 * wpl * height; 

对我来说,我无法理解为什么像素应该以这种方式在内存中平铺。有什么想法吗?

在图像的位图表示中,单个图像通常由一个字节(字)块按顺序表示。如果使用行主顺序,则还可以将其视为二维数组,并将其像
arr[row][col]
那样索引,如果将其强制转换为适当的数组类型(例如在
C
code中)

如果
depth
是单个像素的位数,
width*depth
是整行的位数

然后,在整数算术中,
(宽度*深度+31)/32
是保存该行所需的最小32位块数

(注意,
+31
是为了强制我们在
宽度*深度
不可完全整除的情况下进行四舍五入。通常,
x/n
会在
C
C++
中进行四舍五入,丢弃余数。但是,如果我们在表达式
(x+(n-1))中四舍五入之前添加
n-1
)/n
,我们确保如果在
x/n
中有任何非零余数,则它与
n-1
相加为
n
的多个倍数,然后丢弃之后的余数。因此,这是一种在(无符号)整数算术中向上取整而不是向下取整的方法。)

整个图像所需的32位块数为
wpl*height
。如果我们乘以
4
,我们得到
4*wpl*height
是整个图像所需的8位块(字节)数


请注意,如果位深度远小于32,例如,如果深度如您所说的是8,这实际上将是相当低效的,因为即使您只需要使用其中的8位,您仍然可以获得每像素32位。但是,位图图像最常见的格式是32位,因此在典型情况下/对于典型格式,不会有太多浪费。

在图像的位图表示中,单个图像通常由一个字节(字)块按顺序表示。如果使用行主顺序,则还可以将其视为二维数组,并将其像
arr[row][col]
那样索引,如果将其强制转换为适当的数组类型(例如在
C
code中)

如果
depth
是单个像素的位数,
width*depth
是整行的位数

然后,在整数算术中,
(宽度*深度+31)/32
是保存该行所需的最小32位块数

(注意,
+31
是为了强制我们在
宽度*深度
不可完全整除的情况下进行四舍五入。通常,
x/n
会在
C
C++
中进行四舍五入,丢弃余数。但是,如果我们在表达式
(x+(n-1))中四舍五入之前添加
n-1
)/n
,我们确保如果在
x/n
中有任何非零余数,则它与
n-1
相加为
n
的多个倍数,然后丢弃之后的余数。因此,这是一种在(无符号)整数算术中向上取整而不是向下取整的方法。)

整个图像所需的32位块数为
wpl*height
。如果我们乘以
4
,我们得到
4*wpl*height
是整个图像所需的8位块(字节)数

请注意,如果位深度远小于32,例如,如果深度如您所说的是8,这实际上将是相当低效的,因为即使您只需要使用其中的8位,您仍然可以获得每像素32位。但是,位图图像最常见的格式是32位,因此在典型情况下/对于典型格式,不会有太多浪费。

+1。为了解决问题的“为什么”部分:4字节对齐要求可以使某些内存访问更快,可能允许使用一些矢量化操作码,并在“扫描线”指针中提供一些位,用于肮脏的实现技巧。+1。为了解决问题的“为什么”部分:4字节对齐要求可以使某些内存访问更快,可能允许使用一些矢量化操作码,并在“扫描线”指针中提供一些位,用于肮脏的实现技巧。