AVCaptureSession输出样本缓冲区保存到CoreData

| 我正在使用AVCaptureVideoDataOutput类中的setSampleBufferDelegate方法使用AVCaptureSession从摄像机捕获帧。委托方法如下所示。您可以看到我转换为UIImage并将其放置在UIImageView中。我想将每个UIImage保存到磁盘并将URL存储在新的ManagedObject中,但是我不知道如何正确地获取ManagedObjectContext,因为每个调用都使用串行调度队列产生一个新线程。谁能提出一种使用CoreData和调度队列的解决方案,这种方式可以构建存储在磁盘上并与managedObject相对应的图像集合。
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
/*Lock the image buffer*/
CVPixelBufferLockBaseAddress(imageBuffer,0); 
/*Get information about the image*/
uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer); 
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
size_t width = CVPixelBufferGetWidth(imageBuffer); 
size_t height = CVPixelBufferGetHeight(imageBuffer);  

/*Create a CGImageRef from the CVImageBufferRef*/
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGImageRef newImage = CGBitmapContextCreateImage(newContext); 

    /*We release some components*/
    CGContextRelease(newContext); 
    CGColorSpaceRelease(colorSpace);

/*We display the result on the image view (We need to change the orientation of the image so that the video is displayed correctly).
     Same thing as for the CALayer we are not in the main thread so ...*/
    UIImage *image= [UIImage imageWithCGImage:newImage scale:1.0 orientation:UIImageOrientationRight];

/*We relase the CGImageRef*/
CGImageRelease(newImage);

[self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];

/*We unlock the  image buffer*/
CVPixelBufferUnlockBaseAddress(imageBuffer,0);

[pool drain];
}
    
已邀请:
推荐的解决方案是为每个线程创建一个新的NSManagedObjectContext,每个线程都指向一个NSPersistentStoreCoordinator。您可能还想听
NSManagedObjectContextDidSaveNotification
,以将更改合并到主线程的上下文中(使用恰当命名的
mergeChangesFromContextDidSaveNotification:
)。 就个人而言,我喜欢在中央使用这样的访问器来处理每个线程的上下文:
- (NSManagedObjectContext *) managedObjectContext {
    NSManagedObjectContext *context = [[[NSThread currentThread] threadDictionary] objectForKey:@\"NSManagedObjectContext\"];
    if (context == nil) {
        context = [[[NSManagedObjectContext alloc] init] autorelease];
        [context setPersistentStoreCoordinator:self.persistentStoreCoordinator];
        [[[NSThread currentThread] threadDictionary] setObject:context forKey:@\"NSManagedObjectContext\"];
    }
    return context;
}
请记住,与传递上下文相比,您无法在线程之间传递NSManagedObjects。相反,您必须传递一个NSManagedObjectID(来自对象的
objectID
属性),然后在目标线程中使用该线程的上下文的
objectWithID:
方法来获取等效的对象。     

要回复问题请先登录注册