2012-04-07 13 views
5

Belirli durumlarda görüntüleri yakalamak istiyorum; örneğin bir düğmeye basıldığında; ama herhangi bir video önizleme ekranı göstermek istemiyorum. Bence bu senaryo için kullanmam gereken captureStillImageAsynchronouslyFromConnection. Şu anda bir video önizlemesi gösterirseniz resim çekebilirim. Ancak, önizleme, aşağıdaki çıkışı ile uygulama çöker göstermek için kod kaldırırsanız:iOS'ta önizlemeyi görüntülemeden görüntü yakalama

2012-04-07 11: 25: 54,898 imCapWOPreview [748: 707] *** uygulamasını Sonlandırma nedeniyle yakalanmamış istisna 'NSInvalidArgumentException', nedeni: '*** - [AVCaptureStillImageOutput captureStillImageAsynchronouslyFromConnection: completionHandler:] - etkin değil/geçersiz bağlantı.' *** İlk atış çağrı yığını: (0x336ee8bf 0x301e21e5 0x3697c35d 0x34187 0x33648435 0x310949eb 0x310949a7 0x31094985 0x310946f5 0x3109502d 0x3109350f 0x31092f01 0x310794ed 0x31078d2d 0x37db7df3 0x336c2553 0x336c24f5 0x336c1343 0x336444dd 0x336443a5 0x37db6fcd 0x310a7743 0x33887 0x3382c) bir durum atma adı sonlandırma (lldb)

BIDViewController.h:

#import <UIKit/UIKit.h> 
#import <AVFoundation/AVFoundation.h> 

@interface BIDViewController : UIViewController 
{ 
    AVCaptureStillImageOutput *stillImageOutput; 
} 
@property (strong, nonatomic) IBOutlet UIView *videoPreview; 
- (IBAction)doCap:(id)sender; 

@end 
Yani burada

benim uygulamasıdır BIDViewController.m içindeki 10

İlgili personel: doCap denir Yukarıdaki kod ile

#import "BIDViewController.h" 

@interface BIDViewController() 

@end 

@implementation BIDViewController 
@synthesize capturedIm; 
@synthesize videoPreview; 

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 
[self setupAVCapture]; 
} 

- (BOOL)setupAVCapture 
{ 
NSError *error = nil; 

AVCaptureSession *session = [AVCaptureSession new]; 
[session setSessionPreset:AVCaptureSessionPresetHigh]; 

/* 
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session]; 
captureVideoPreviewLayer.frame = self.videoPreview.bounds; 
[self.videoPreview.layer addSublayer:captureVideoPreviewLayer];  
*/ 

// Select a video device, make an input 
AVCaptureDevice *backCamera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:backCamera error:&error]; 
if (error) 
    return NO; 
if ([session canAddInput:input]) 
    [session addInput:input]; 

// Make a still image output 
stillImageOutput = [AVCaptureStillImageOutput new]; 
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil]; 
[stillImageOutput setOutputSettings:outputSettings];  
if ([session canAddOutput:stillImageOutput]) 
    [session addOutput:stillImageOutput]; 

[session startRunning]; 

return YES; 
} 

- (IBAction)doCap:(id)sender { 
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; } 
} 

[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection 
    completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *__strong error) { 
     // Do something with the captured image 
    }]; 

} 

, ardından çökme meydana gelir. Öte yandan, ben

/* 
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session]; 
captureVideoPreviewLayer.frame = self.videoPreview.bounds; 
[self.videoPreview.layer addSublayer:captureVideoPreviewLayer];  
*/ 

o zaman sorunsuz çalışır setupAVCapture fonksiyonunda aşağıdaki yorumları kaldırmak eğer. Özetle, sorularım şunlardır: Önizlemeyi göstermeden kontrollü örneklerde görüntüleri nasıl çekebilirim?

+0

en basit yol 'self.videoPreview.hidden = YES olacaktır;' – Felix

+0

kod benim iphone 4S – Felix

+0

@ phix23 üzerinde çalışıyor VideoPreview benim için de çalışıyordu ... Sonra bir sonraki soru; Bu yaklaşımla bir performans cezası var mı? diğer bir deyişle, video önizleme verilerini gizli bir katmana göndermek için harcanan fazla işlenmedir? –

cevap

8

Ön kameradan (varsa) veya arka kamerayı kullanarak çekmek için aşağıdaki kodu kullanırım. IPhone 4S'de iyi çalışıyor. captureStillImageAsynchronouslyFromConnection:stillImageConnection geçti connection geçersiz olduğunu bir istisna büyütürken tarafından nerede

-(void)viewDidLoad{ 

    AVCaptureSession *session = [[AVCaptureSession alloc] init]; 
    session.sessionPreset = AVCaptureSessionPresetMedium; 

    AVCaptureDevice *device = [self frontFacingCameraIfAvailable]; 

    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 is a global variable in .h file: "AVCaptureStillImageOutput *stillImageOutput;" 
    stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; 
    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil]; 
    [stillImageOutput setOutputSettings:outputSettings]; 

    [session addOutput:stillImageOutput]; 

    [session startRunning]; 
} 

-(AVCaptureDevice *)frontFacingCameraIfAvailable{ 

    NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; 
    AVCaptureDevice *captureDevice = nil; 

    for (AVCaptureDevice *device in videoDevices){ 

     if (device.position == AVCaptureDevicePositionFront){ 

      captureDevice = device; 
      break; 
     } 
    } 

    // couldn't find one on the front, so just get the default video device. 
    if (!captureDevice){ 

     captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    } 

    return captureDevice; 
} 

-(IBAction)captureNow{ 

    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 if you want to. 
      NSLog(@"attachements: %@", exifAttachments); 
     } 
     else 
      NSLog(@"no attachments"); 

     NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer]; 
     UIImage *image = [[UIImage alloc] initWithData:imageData]; 

     self.vImage.image = image; 
    }]; 
} 
+0

Harika çalışıyor. Teşekkürler ! –

+1

stillImageOutput.connections öğesinde hata alıyorum veya 0 nesnesi içeriyor. Yanlış olan ne? –

+0

Bu gerçekten iyi bir çözümdür. Ancak görüntü yakalandıktan hemen sonra ekran kapanır. SnapChat uygulamasında bunun gibi değil. Davranışı SnapChat uygulamasında nasıl bulabilirim? – Satyam

1

Eh, ben de benzer bir sorunla karşı karşıya edildi. Daha sonra, oturum için properties ve değerleri korumak için stillImageOutPut yaptığımda, sorunun çözüldüğünü anladım.

İlgili konular