我想了解在构建NSBitmapImageRep时如何计算"bytesPerRow"(在我的情况下,是从浮点数组映射到灰度位图)。
澄清这个细节将有助于我理解内存是如何从浮点数组映射到字节数组的(0-255,无符号字符;下面的代码中没有显示这两个数组)。
苹果公司的文件称,这个数字是"根据图像的宽度、每个样本的位数,以及如果数据是网格配置,每个像素的样本数计算得出的。"
我在进行这个"计算"时遇到了麻烦,所以我设置了一个简单的循环来根据经验找到结果。以下代码运行良好:
int Ny = 1; // Ny is arbitrary, note that BytesPerPlane is calculated as we would expect = Ny*BytesPerRow;
for (int Nx = 0; Nx<320; Nx+=64) {
// greyscale image representation:
NSBitmapImageRep *dataBitMapRep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes: nil // allocate the pixel buffer for us
pixelsWide: Nx
pixelsHigh: Ny
bitsPerSample: 8
samplesPerPixel: 1
hasAlpha: NO
isPlanar: NO
colorSpaceName: NSCalibratedWhiteColorSpace // 0 = black, 1 = white
bytesPerRow: 0 // 0 means "you figure it out"
bitsPerPixel: 8]; // bitsPerSample must agree with samplesPerPixel
long rowBytes = [dataBitMapRep bytesPerRow];
printf("Nx = %d; bytes per row = %lu n",Nx, rowBytes);
}
并产生结果:
Nx = 0; bytes per row = 0
Nx = 64; bytes per row = 64
Nx = 128; bytes per row = 128
Nx = 192; bytes per row = 192
Nx = 256; bytes per row = 256
因此,我们看到字节/行以64字节的增量跳跃,即使Nx以1的增量一直增加到320(我没有显示所有Nx值)。还要注意,Nx=320(max)对于该讨论是任意的。
那么,从为字节数组分配和映射内存的角度来看,"每行字节数"是如何根据第一性原理计算的呢?上面的结果是否使来自单个扫描线的数据可以在"字"长度边界上对齐(在我的MacBook Pro上为64位)?
感谢您的任何见解,我很难想象这是如何工作的。
为bytesPerRow:
传递0比您在评论中所说的意义更大。来自文件:
如果传入
rowBytes
值0,则分配的位图数据可能会被填充到长字或更大的边界上,以提高性能…传入一个非零值可以指定精确的行前进。
因此,您看到它一次增加64个字节,因为这就是AppKit决定将其四舍五入的原因。
每行字节数的最低要求要简单得多。它是每像素字节数乘以每行像素数。仅此而已。
对于由浮点支持的位图图像rep,您可以将sizeof(float) * 8
传递给bitsPerSample
,每个像素的字节数将为sizeof(float) * samplesPerPixel
。每行的字节数紧随其后;将每个像素的字节数乘以以像素为单位的宽度。
同样,如果它是由无符号字节支持的,则将sizeof(unsigned char) * 8
传递给bitsPerSample
,每个像素的字节数将为sizeof(unsigned char) * samplesPerPixel
。