2012-12-31 108 views
3

我可以从iOS后置摄像头捕捉图像。除了我想让它根据我的UIView中的边界拍摄图片以外,所有内容都完美无缺地工作。捕获图像的边界?

我的代码如下:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 

    session = [[AVCaptureSession alloc] init]; 

    session.sessionPreset = AVCaptureSessionPresetMedium; 

    captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session]; 
    captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 
    captureVideoPreviewLayer.frame = vImagePreview.bounds; 
    [vImagePreview.layer addSublayer:captureVideoPreviewLayer]; 

    AVCaptureDevice *device = [self backFacingCameraIfAvailable]; 
    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]; 
    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; 
     } 
    } 

    [session startRunning]; 

    [session addOutput:stillImageOutput]; 
} 

-(AVCaptureDevice *)backFacingCameraIfAvailable{ 

    NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; 
    AVCaptureDevice *captureDevice = nil; 
    for (AVCaptureDevice *device in videoDevices){ 
     if (device.position == AVCaptureDevicePositionBack){ 
      captureDevice = device; 
      break; 
     } 
    } 

    // couldn't find one on the back, so just get the default video device. 
    if (!captureDevice){ 
     captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    } 
    return captureDevice; 
} 

而且下面是捕捉图像的代码:

- (IBAction)captureTask { 
    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]; 
     stillImage = image; 

    }]; 
} 

我现在面临的问题是,它的拍照,并保存到stillImage但是,从我所知道的情况来看,该图像是用于整个iPhone屏幕的。这不是我创建的UIView *vImagePreview的界限。有没有办法剪切捕获图像的边界?

[编辑]

阅读文档后,我意识到图像是正确的解决方案,为每个在这里:session.sessionPreset = AVCaptureSessionPresetMedium;。有没有办法让图像像一个正方形?像Instagram如何制作他们的图片?所有会话预设根据文档是不是在所有的广场:(

我用以下尝试:

captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResize;

但是,它只调整大小以适应当前视图的图像,没有按” 。T!做一个正方形图像

回答

6

我理解你的无奈,预设应该是定制的或有更多的选择我做我的图片是裁剪他们围绕中心,为此,我写了下面的代码:

- (UIImage *)crop:(UIImage *)image from:(CGSize)src to:(CGSize)dst 
{ 
    CGPoint cropCenter = CGPointMake((src.width/2), (src.height/2)); 
    CGPoint cropStart = CGPointMake((cropCenter.x - (dst.width/2)), (cropCenter.y - (dst.height/2))); 
    CGRect cropRect = CGRectMake(cropStart.x, cropStart.y, dst.width, dst.height); 
    CGImageRef cropRef = CGImageCreateWithImageInRect(image.CGImage, cropRect); 
    UIImage* cropImage = [UIImage imageWithCGImage:cropRef]; 
    CGImageRelease(cropRef); 

    return cropImage; 
} 

其中src代表原始尺寸,dst代表裁剪的尺寸;和image当然是你想要裁剪的图像。

+0

虽然不理想,你的解决方案工作。希望他们通过拍照解决其中的一些问题 – KVISH

0

如果设备是Retina显示屏, 那么这张截图就像提到如下:

if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00) 
{ 
    CGPoint cropCenter = CGPointMake((src.width), (src.height)); 
    CGPoint cropStart = CGPointMake((cropCenter.x - (dst.width)), (cropCenter.y - (dst.height))); 
    CGRect cropRect = CGRectMake(cropStart.x, cropStart.y, dst.width*2, dst.height*2); 
    CGImageRef cropRef = CGImageCreateWithImageInRect(image.CGImage, cropRect); 
    UIImage* cropImage = [UIImage imageWithCGImage:cropRef]; 
    CGImageRelease(cropRef); 
    return cropImage; 
} 
else 
{ 
    CGPoint cropCenter = CGPointMake((src.width/2), (src.height/2)); 
    CGPoint cropStart = CGPointMake((cropCenter.x - (dst.width/2)), (cropCenter.y - (dst.height/2))); 
    CGRect cropRect = CGRectMake(cropStart.x, cropStart.y, dst.width, dst.height); 
    CGImageRef cropRef = CGImageCreateWithImageInRect(image.CGImage, cropRect); 
    UIImage* cropImage = [UIImage imageWithCGImage:cropRef]; 
    CGImageRelease(cropRef); 

    return cropImage; 
}