2012-11-07 36 views
0

默認的iPhone相機應用程序拍攝照片後,會出現預覽,並且圖像會動畫到相機滾動按鈕。我正試圖複製這個動畫。ios AVCaptureVideoPreviewLayer捕捉當前圖像

session = [[AVCaptureSession alloc] init]; 
session.sessionPreset = AVCaptureSessionPresetPhoto; 

CALayer *viewLayer = self.vImagePreview.layer; 
NSLog(@"viewLayer = %@", viewLayer); 

captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session]; 

captureVideoPreviewLayer.frame = CGRectMake(0, 0, 322, 425); 
[self.vImagePreview.layer addSublayer:captureVideoPreviewLayer]; 



device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 

NSError *error = nil; 
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; 
if (!input) { 
    // Handle the error appropriately. 
    NSLog(@"ERROR: trying to open camera: %@", error); 
} 
[session addInput:input]; 
_stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; 
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil]; 
[_stillImageOutput setOutputSettings:outputSettings]; 
[session addOutput:_stillImageOutput]; 

這是我拍攝圖像:

AVCaptureConnection *videoConnection = nil; 
for (AVCaptureConnection *connection in _stillImageOutput.connections) 
{ 
    for (AVCaptureInputPort *port in [connection inputPorts]) 
    { 
     if ([[port mediaType] isEqual:AVMediaTypeVideo]) 
     { 
      videoConnection = connection; 
      break; 
     } 
    } 
    if (videoConnection) { break; } 
} 
NSLog(@"about to request a capture from: %@", _stillImageOutput); 
[_stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) 
{ 
    CFDictionaryRef exifAttachments = CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, NULL); 
    if (exifAttachments) 
    { 
     // Do something with the attachments. 
     NSLog(@"attachements: %@", exifAttachments); 
    } 
    else 
     NSLog(@"no attachments"); 

    NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer]; 
    UIImage *image = [[UIImage alloc] initWithData:imageData]; 
    UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); 
}];  

這需要完整的照片圖像,但我也需要從AVCaptureVideoPreviewLayer的圖像,所以我可以用它來複制動畫。如何獲取AVCaptureVideoPreviewLayer中當前顯示的圖像?

回答

-1

做到這一點的辦法是另一個輸出添加到會話:

frameOutput = [[AVCaptureVideoDataOutput alloc] init]; 
frameOutput.videoSettings = @{(id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA)}; 

[frameOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; 

而且一旦你有,你可以得到的緩衝當前圖像:

 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
    fromConnection:(AVCaptureConnection *)connection{ 


// Create a UIImage from the sample buffer data 
UIImage *image = [self imageFromSampleBuffer:sampleBuffer]; 
rotatedScreenImage = rotateUIImage(image, 90.0);} 
- (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer{ 
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 

CVPixelBufferLockBaseAddress(imageBuffer, 0); 

// Get the number of bytes per row for the pixel buffer 
void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); 

// 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 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

// Create a bitmap graphics context with the sample buffer data 
CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, 
              bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
// Create a Quartz image from the pixel data in the bitmap graphics context 
CGImageRef quartzImage = CGBitmapContextCreateImage(context); 
// Unlock the pixel buffer 
CVPixelBufferUnlockBaseAddress(imageBuffer,0); 


// Free up the context and color space 
CGContextRelease(context); 
CGColorSpaceRelease(colorSpace); 

// Create an image object from the Quartz image 
UIImage *image = [UIImage imageWithCGImage:quartzImage]; 

// Release the Quartz image 
CGImageRelease(quartzImage); 

return (image); 

}

而且返回(圖像)實際上是在屏幕緩衝區上。