仅在模拟器中出现 CGContext 错误?
Posted
技术标签:
【中文标题】仅在模拟器中出现 CGContext 错误?【英文标题】:CGContext Errors only in simulator? 【发布时间】:2013-08-01 04:12:28 【问题描述】:在测试我的应用程序是否存在任何错误时,我注意到在模拟器中,当我调用我的一个函数将图像设置为 UIImageView 时,会引发一堆 CGContext 错误并且图像永远不会被设置。但是在我的设备上(我在 iPhone 5、iPhone 3GS 和 iPad 3 上进行了测试),这些 CGContext 错误都没有出现,并且图像设置正常。
无论如何,我都在寻找任何可以实现这一点的 CGContext 代码,以下是唯一涉及 CGContext 的方法:
- (void)setCropRect:(CGRect)cropRect
if(!CGRectEqualToRect(_cropRect,cropRect))
_cropRect = cropRect;
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.f);
CGContextRef context = UIGraphicsGetCurrentContext();
[[UIColor blackColor] setFill];
UIRectFill(self.bounds);
CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] colorWithAlphaComponent:0.5].CGColor);
CGContextStrokeRect(context, _cropRect);
[[UIColor clearColor] setFill];
UIRectFill(CGRectInset(_cropRect, 1, 1));
self.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
- (CGImageRef)newScaledImage:(CGImageRef)source withOrientation:(UIImageOrientation)orientation toSize:(CGSize)size withQuality:(CGInterpolationQuality)quality
CGSize srcSize = size;
CGFloat rotation = 0.0;
switch(orientation)
case UIImageOrientationUp:
rotation = 0;
break;
case UIImageOrientationDown:
rotation = M_PI;
break;
case UIImageOrientationLeft:
rotation = M_PI_2;
srcSize = CGSizeMake(size.height, size.width);
break;
case UIImageOrientationRight:
rotation = -M_PI_2;
srcSize = CGSizeMake(size.height, size.width);
break;
default:
break;
CGContextRef context = CGBitmapContextCreate(NULL,
size.width,
size.height,
8, //CGImageGetBitsPerComponent(source),
0,
CGImageGetColorSpace(source),
kCGImageAlphaNoneSkipFirst//CGImageGetBitmapInfo(source)
);
CGContextSetInterpolationQuality(context, quality);
CGContextTranslateCTM(context, size.width/2, size.height/2);
CGContextRotateCTM(context,rotation);
CGContextDrawImage(context, CGRectMake(-srcSize.width/2 ,
-srcSize.height/2,
srcSize.width,
srcSize.height),
source);
CGImageRef resultRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
return resultRef;
- (CGImageRef)newTransformedImage:(CGAffineTransform)transform
sourceImage:(CGImageRef)sourceImage
sourceSize:(CGSize)sourceSize
sourceOrientation:(UIImageOrientation)sourceOrientation
outputWidth:(CGFloat)outputWidth
cropSize:(CGSize)cropSize
imageViewSize:(CGSize)imageViewSize
CGImageRef source = [self newScaledImage:sourceImage
withOrientation:sourceOrientation
toSize:sourceSize
withQuality:kCGInterpolationNone];
CGFloat aspect = cropSize.height/cropSize.width;
CGSize outputSize = CGSizeMake(outputWidth, outputWidth*aspect);
CGContextRef context = CGBitmapContextCreate(NULL,
outputSize.width,
outputSize.height,
CGImageGetBitsPerComponent(source),
0,
CGImageGetColorSpace(source),
CGImageGetBitmapInfo(source));
CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
CGContextFillRect(context, CGRectMake(0, 0, outputSize.width, outputSize.height));
CGAffineTransform uiCoords = CGAffineTransformMakeScale(outputSize.width/cropSize.width,
outputSize.height/cropSize.height);
uiCoords = CGAffineTransformTranslate(uiCoords, cropSize.width/2.0, cropSize.height/2.0);
uiCoords = CGAffineTransformScale(uiCoords, 1.0, -1.0);
CGContextConcatCTM(context, uiCoords);
CGContextConcatCTM(context, transform);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawImage(context, CGRectMake(-imageViewSize.width/2.0,
-imageViewSize.height/2.0,
imageViewSize.width,
imageViewSize.height)
,source);
CGImageRef resultRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGImageRelease(source);
return resultRef;
这些是 CGContext 错误:
Jul 31 23:37:37 app[10190] <Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 16 bits/pixel; 1-component color space; kCGImageAlphaNoneSkipFirst; 1504 bytes/row.
Jul 31 23:37:37 app[10190] <Error>: CGContextSetInterpolationQuality: invalid context 0x0
Jul 31 23:37:37 app[10190] <Error>: CGContextTranslateCTM: invalid context 0x0
Jul 31 23:37:37 app[10190] <Error>: CGContextRotateCTM: invalid context 0x0
Jul 31 23:37:37 app[10190] <Error>: CGContextDrawImage: invalid context 0x0
Jul 31 23:37:37 app[10190] <Error>: CGBitmapContextCreateImage: invalid context 0x0
Jul 31 23:37:37 app[10190] <Error>: CGBitmapContextCreate: unsupported parameter combination: 0 integer bits/component; 0 bits/pixel; 0-component color space; kCGImageAlphaNone; 0 bytes/row.
Jul 31 23:37:37 app[10190] <Error>: CGContextSetFillColorWithColor: invalid context 0x0
Jul 31 23:37:37 app[10190] <Error>: CGContextFillRects: invalid context 0x0
Jul 31 23:37:37 app[10190] <Error>: CGContextConcatCTM: invalid context 0x0
Jul 31 23:37:37 app[10190] <Error>: CGContextConcatCTM: invalid context 0x0
Jul 31 23:37:37 app[10190] <Error>: CGContextScaleCTM: invalid context 0x0
Jul 31 23:37:37 app[10190] <Error>: CGContextDrawImage: invalid context 0x0
Jul 31 23:37:37 app[10190] <Error>: CGBitmapContextCreateImage: invalid context 0x0
这些是我的应用程序中唯一使用 CGContexts 的方法。但就像我说的,这只发生在模拟器中,而不是我测试过的设备上。
无论如何,这有什么特别的原因吗?或者有什么办法可以解决这个问题?
谢谢大家!
CGContextRef context = CGBitmapContextCreate(NULL,
size.width,
size.height,
CGImageGetBitsPerComponent(source), //8,
0,
CGImageGetColorSpace(source),
CGImageGetBitmapInfo //kCGImageAlphaNoneSkipFirst(source)
);
【问题讨论】:
如果您告诉我们“一堆 CGContext 错误”是什么会有所帮助。 抱歉,我添加了它们。 【参考方案1】:很可能,您对CGBitmapContextCreate
的第一次调用失败了,因为您要求它做一些它不能做的事情。您可以在第一条错误消息中看到:
CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 16 bits/pixel; 1-component color space; kCGImageAlphaNoneSkipFirst; 1504 bytes/row.
CGBitmapContextCreate
返回 NULL,其余故障从那里级联。 (您不能对 NULL 上下文进行操作,并且在 NULL 上下文上调用 CGBitmapContextGetImage()
会给您一个 NULL 图像,您同样无法对它做任何有用的事情。)
CGBitmapContextCreate
的文档指出:
有关支持的像素格式列表,请参阅Quartz 2D Programming Guide 的“Graphics Contexts” 章节中的“支持的像素格式”。
这是该列表中的direct link。
【讨论】:
啊,好吧。我对 CGContexts 不是很熟悉,所以你可能比我知道的更多,但是这个问题的第二个答案:***.com/questions/5545600/… 会解决这个问题并完成与我现在的代码相同的操作吗? SO 并不总是以相同的顺序显示答案,所以我不知道您认为哪个是第二个。如果你的意思是this one,代码是错误的:它指定了格式的一部分(RGB 颜色空间),但仍然从原始图像中获取一些部分(每个组件的位数,bitmapInfo),所以你仍然可能会遇到类似的错误。 This answer 可能更好。事实上,你几乎就在那里,只需使用在硬编码 8 位/像素和 kCGImageAlphaNoneSkipFirst 的行中注释掉的代码。 感谢您在这里帮助我,但按照您的建议进行操作并不能解决问题。我在原始问题的末尾发布了我从您的回复中解释的内容,但它导致了相同的 CGContext 错误。 您的意思是CGImageGetBitmapInfo(source)
,而不仅仅是CGImageGetBitmapInfo
,对吗? (你的方式甚至不应该编译,或者至少应该给出编译器警告。)
但是为什么这个错误发生在模拟器而不是设备上呢?你发现了吗?【参考方案2】:
您对CGBitmapContextCreate
的两次调用都使用了不受支持的位/组件 - 位/像素组合(正如 CGContext 错误告诉您的那样)。
有关支持的像素格式列表,请参阅Quartz 2D Programming Guide 中的表 2.1
【讨论】:
以上是关于仅在模拟器中出现 CGContext 错误?的主要内容,如果未能解决你的问题,请参考以下文章
从 drawRect 调用的方法中出现无效的 CGContext 错误
读取 NSFetchedResultsController 的 fetchedObjects 属性时出现 EXC_BAD_ACCESS 错误(仅在模拟器上)