Objective c 在这个CGBitmapContextCreate中,为什么bytesPerRow为0?

Objective c 在这个CGBitmapContextCreate中,为什么bytesPerRow为0?,objective-c,ios,core-graphics,Objective C,Ios,Core Graphics,我在Apple的示例代码中注意到,它们通常在CGBitmapContextCreate的bytesPerRow参数中提供值0。例如,这来自示例项目 CGContextRef gradientBitmapContext = CGBitmapContextCreate(NULL, pixelsWide, pixelsHigh, 8, 0, colorSpace, kCGImag

我在Apple的示例代码中注意到,它们通常在CGBitmapContextCreate的bytesPerRow参数中提供值0。例如,这来自示例项目

CGContextRef gradientBitmapContext = CGBitmapContextCreate(NULL, pixelsWide, pixelsHigh,  
                                                            8, 0, colorSpace, kCGImageAlphaNone);
这对我来说似乎很奇怪,因为我一直采用图像宽度乘以每像素字节数的方法。我试着把一个0换成我自己的代码,并进行了测试。果然,它仍然有效

size_t bitsPerComponent = 8;
size_t bytesPerPixel = 4;
size_t bytesPerRow = reflectionWidth * bytesPerPixel;   

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL,
                                             reflectionWidth,
                                             reflectionHeight,
                                             bitsPerComponent,
                                             0, // bytesPerRow ??
                                             colorSpace,
                                             kCGImageAlphaPremultipliedLast);
根据文档,bytesPerRow应该是“位图每行使用的内存字节数”


那交易是什么?何时可以提供零,何时必须计算准确值?采用这种或那种方法是否会影响性能?

我的理解是,如果传入零,它将根据bitsPerComponent和width参数计算每行的字节数。您可能需要在每行字节的末尾添加额外的填充(如果您的设备需要,或者其他一些限制)。在这种情况下,您可以传递一个不仅仅是宽度*(每像素字节数)的值。我想这在现代I/MacOS开发中可能永远都不需要,除了一些奇怪的边缘案例优化。

听起来很合理。如果苹果在文档中的某个地方澄清了这一点,那就太好了(如果它在那里,我还没有找到它)。我发现过分依赖未记录的行为有些令人不安。bytesPerRow位图每行使用的内存字节数。如果数据参数为NULL,则传递值0会导致自动计算该值。我想我应该在此处添加(从CGBitmapContext标头):“每个像素的字节数等于
(bitsPerComponent*组件数+7)/8.位图的每一行都由
bytesPerRow'字节组成,这些字节必须至少是width*bytes per pixel'字节;此外,bytesPerRow'必须是每个像素字节数的整数倍。“@chrisp u plz能解释一下组件的数量吗?您发布的示例:CGBitmapContextCreate(NULL,pixelsWide,pixelsHigh,8,0,colorSpace,kCGImageAlphaNone);无效。您无法创建没有alpha通道的位图上下文。顺便说一句——如果您查看应用程序的日志输出(您可能必须在Console.app中检查系统日志)每当您尝试使用无效参数创建位图上下文时,
CGBitmapContextCreate
将打印错误消息。