代码如下:
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
CGContextRef context = ctx;
CGContextRetain(context);
CGContextSetInterpolationQuality(context, kCGInterpolationNone);
CGContextSetLineCap(context, kCGLineCapButt);
CGContextSetLineWidth(context, 1);
CGContextSetRGBStrokeColor(context, 0, 0, 0, 0.8);
// draw image
CGContextSaveGState(context);
CGAffineTransform flipVertical = CGAffineTransformMake(
1, 0, 0, -1, 0, layer.bounds.size.height
);
CGContextConcatCTM(context, flipVertical);
CGContextDrawImage(context, layer.bounds, imageRef);
CGContextRestoreGState(context);
// draw borders
CGContextAddRect(context, layer.bounds);
CGContextDrawPath(context, kCGPathStroke);
CGFloat apertureSize = scaleFactor * (2 * samplingLevel - 1) - 1;
CGFloat x = self.bounds.size.width / 2 - apertureSize / 2;
CGFloat y = self.bounds.size.height / 2 - apertureSize / 2;
CGRect apertureRect = CGRectMake(x, y, apertureSize, apertureSize);
// draw the aperture
CGContextSaveGState(context);
CGContextSetRGBStrokeColor(context, 0, 0, 0, 1);
CGContextSetShouldAntialias(context, NO);
CGContextStrokeRect(context, apertureRect);
CGContextRestoreGState(context);
CGContextRelease(context);
}
它崩溃了:
(lldb) thread backtrace
* thread #1: tid = 0x1c03, 0x37537a5c CoreGraphics`argb32_image_mark_rgb32 + 800, stop reason = EXC_BAD_ACCESS (code=1, address=0x7314b0)
frame #0: 0x37537a5c CoreGraphics`argb32_image_mark_rgb32 + 800
frame #1: 0x3750e400 CoreGraphics`argb32_image + 5948
frame #2: 0x313c5894 libRIP.A.dylib`ripl_Mark + 16
frame #3: 0x313ca68a libRIP.A.dylib`ripl_BltImage + 998
frame #4: 0x313c2468 libRIP.A.dylib`ripc_RenderImage + 180
frame #5: 0x313be300 libRIP.A.dylib`ripc_DrawImage + 584
frame #6: 0x3750a928 CoreGraphics`CGContextDelegateDrawImage + 48
frame #7: 0x3750a794 CoreGraphics`CGContextDrawImage + 292
frame #8: 0x00166e34 MyApp`-[MyView drawLayer:inContext:] + 380 at MyView.m:43
frame #9: 0x33f054e4 QuartzCore`-[CALayer drawInContext:] + 116
frame #10: 0x33f04b3e QuartzCore`CABackingStoreUpdate_ + 1782
frame #11: 0x33f04334 QuartzCore`CA::Layer::display_() + 956
frame #12: 0x33f03f60 QuartzCore`CA::Layer::display() + 128
任何人都知道为什么?谢谢! 我猜它是由CGImage或CGContext引起的,但是在调试时它们都是非null。 我用于更新视图的图像是从摄像头捕获生成的。
答案 0 :(得分:4)
我使用apple(AV Foundation Programming Guide)提供的示例代码来创建imageRef
。
UIImage *imageFromSampleBuffer(CMSampleBufferRef sampleBuffer) {
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
// Lock the base address of the pixel buffer.
CVPixelBufferLockBaseAddress(imageBuffer,0);
// Get the number of bytes per row for the pixel buffer.
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
// Get the pixel buffer width and height.
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
// Create a device-dependent RGB color space.
static CGColorSpaceRef colorSpace = NULL;
if (colorSpace == NULL) {
colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL) {
// Handle the error appropriately.
return nil;
}
}
// Get the base address of the pixel buffer.
void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
// Get the data size for contiguous planes of the pixel buffer.
size_t bufferSize = CVPixelBufferGetDataSize(imageBuffer);
// Create a Quartz direct-access data provider that uses data we supply.
CGDataProviderRef dataProvider =
CGDataProviderCreateWithData(NULL, baseAddress, bufferSize, NULL);
// Create a bitmap image from data supplied by the data provider.
CGImageRef cgImage =
CGImageCreate(width, height, 8, 32, bytesPerRow,
colorSpace, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little,
dataProvider, NULL, true, kCGRenderingIntentDefault);
CGDataProviderRelease(dataProvider);
// Create and return an image object to represent the Quartz image.
UIImage *image = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
return image;
}
请注意以下这一行:
CGDataProviderRef dataProvider =
CGDataProviderCreateWithData(NULL, baseAddress, bufferSize, NULL);
CMSampleBuffer
直接用于创建CGImageRef
,因此缓存释放后CGImageRef
将无效。
使用缓冲区数据的副本将解决此问题:
NSData *data = [NSData dataWithBytes:baseAddress length:bufferSize];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
答案 1 :(得分:3)
我遇到了同样的问题,但问题与ARC有关并正确发布了CGImageRef。确保调用以下内容:
CGImageRelease(imageRef);
答案 2 :(得分:0)
变化
CGDataProviderRef dataProvider =
CGDataProviderCreateWithData(NULL, baseAddress, bufferSize, NULL);
到
NSData *data = [NSData dataWithBytes:baseAddress length:bufferSize];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
非常有帮助。