CGBitmapContextCreate按原UIImage宽高减半创建时返回NULL求助
CGBitmapContextCreate 返回 NULL 的排查与解决方案
我碰到过好多次这个问题了,结合你说的「宽高是原UIImage尺寸除以2」的场景,大概率是这几个常见坑导致的,给你逐一拆解:
1. 宽高参数必须是整数
CGBitmapContextCreate 的宽高参数是 size_t 类型(无符号整数),如果你的原尺寸是奇数,除以2后会得到小数(比如原宽5→2.5),直接传这种小数会被系统截断或者触发参数校验失败,返回NULL。
解决代码:把宽高转成整数,推荐用 round() 保证精度,避免截断误差:
// 先把宽高转为整数 size_t bitmapWidth = (size_t)round(newRect.size.width); size_t bitmapHeight = (size_t)round(newRect.size.height); // 再创建上下文 CGContextRef bitmap = CGBitmapContextCreate(NULL, bitmapWidth, bitmapHeight, CGImageGetBitsPerComponent(imageRef), 0, CGImageGetColorSpace(imageRef), CGImageGetBitmapInfo(imageRef));
2. 行字节数对齐问题
很多iOS设备要求图形上下文的每行字节数必须是4的倍数(32位内存对齐),如果你的宽高和位深组合后不满足这个要求,也会创建失败。比如当原图片是24位RGB(每个像素3字节),宽度是奇数的话,每行字节数就是奇数,直接触发对齐错误。
解决代码:手动计算对齐后的行字节数,代替传0让系统自动计算:
size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef); size_t componentsPerPixel = CGImageGetNumberOfComponents(imageRef); size_t bytesPerPixel = (bitsPerComponent * componentsPerPixel) / 8; // 对齐到4字节的倍数 size_t bytesPerRow = (bitmapWidth * bytesPerPixel + 3) & ~3; CGContextRef bitmap = CGBitmapContextCreate(NULL, bitmapWidth, bitmapHeight, bitsPerComponent, bytesPerRow, CGImageGetColorSpace(imageRef), CGImageGetBitmapInfo(imageRef));
3. 颜色空间/位图信息不兼容
有些特殊格式的图片(比如CMYK颜色空间、带非标准alpha通道的图),直接复用原图片的颜色空间和位图信息可能会和当前设备上下文不兼容,导致创建失败。
临时排查方案:试试用通用的sRGB颜色空间和标准alpha格式创建,看是否能成功:
CGColorSpaceRef rgbSpace = CGColorSpaceCreateDeviceRGB(); // 使用32位RGBA标准格式 CGContextRef bitmap = CGBitmapContextCreate(NULL, bitmapWidth, bitmapHeight, 8, bytesPerRow, rgbSpace, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(rgbSpace);
额外调试技巧
创建后加个判断,打印错误信息,方便定位具体问题:
if (!bitmap) { NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:kCGErrorInvalidArgument userInfo:@{NSLocalizedDescriptionKey:@"创建位图上下文失败"}]; NSLog(@"Bitmap context creation failed: %@", error); }
内容的提问来源于stack exchange,提问作者Nyein Ei Ei Tun
相关产品推荐
相关产品推荐

