0

The code is below:

- (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);
}

and it crashes with:

(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

Anyone knows why? Thanks! I guess it is caused by either CGImage or CGContext, but both of them are Non-null when debugging. The image I used to update the view is generated from camera capturing.

4

3 に答える 3

4

アップルが提供するサンプルコード ( 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);

CMSampleBufferCGImageRefを作成するために直接使用されるためCGImageRef、バッファが解放されると無効になります。

バッファ データのコピーを使用すると、この問題が解決されます。

NSData *data = [NSData dataWithBytes:baseAddress length:bufferSize];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
于 2012-05-29T12:01:17.283 に答える
3

同じ問題が発生しましたが、問題は ARC と CGImageRef の適切なリリースに関連していました。以下が呼び出されていることを確認します。

CGImageRelease(imageRef);
于 2012-12-24T02:14:10.727 に答える