我想了解在构建NSBitmapImageRep时如何计算“bytesPerRow”(在我的例子中,从浮点数组映射到灰度位图)。
澄清这个细节将有助于我理解如何将内存从一个浮点数组映射到一个字节数组(0-255,无符号字符;这些数组都不会显示在下面的代码中)。
Apple文档说这个数字是“从图像的宽度,每个样本的位数,以及,如果数据是网格配置,每个像素的样本数”。
我无法遵循这个“计算”,因此我设置了一个简单的循环来根据经验查找结果。以下代码运行正常:
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位)上对齐吗?
感谢任何见解,无法描述其工作原理。
答案 0 :(得分:2)
bytesPerRow:
传递0意味着比您在评论中说的更多。来自文档:
如果传入
rowBytes
值为0,则分配的位图数据可能会填充为长字或更大的边界以提高性能。 ...传入非零值可以指定精确的行前进。
所以你看到它一次增加64个字节,因为这就是AppKit决定将其整理的方式。
每行字节的最低要求要简单得多。它是每像素的字节数乘以每行像素。就是这样。
对于由浮点数支持的位图图像代表,您为sizeof(float) * 8
传递bitsPerSample
,每像素字节为sizeof(float) * samplesPerPixel
。每行字节数由此开始;你将每像素的字节乘以宽度(以像素为单位)。
同样,如果它由无符号字节支持,则为sizeof(unsigned char) * 8
传递bitsPerSample
,每像素字节为sizeof(unsigned char) * samplesPerPixel
。