2011-08-07 20 views
8

Tôi có một số mã khá cơ bản để chụp ảnh tĩnh bằng cách sử dụng AVFoundation.Tại sao chụp ảnh bằng AVFoundation cho tôi hình ảnh 480x640 khi cài đặt trước là 640x480?

AVCaptureDeviceInput *newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self backFacingCamera] error:nil]; 

    AVCaptureStillImageOutput *newStillImageOutput = [[AVCaptureStillImageOutput alloc] init]; 

    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: 
            AVVideoCodecJPEG, AVVideoCodecKey, 
            nil]; 


    [newStillImageOutput setOutputSettings:outputSettings]; 
    [outputSettings release]; 


    AVCaptureSession *newCaptureSession = [[AVCaptureSession alloc] init]; 
    [newCaptureSession beginConfiguration]; 
    newCaptureSession.sessionPreset = AVCaptureSessionPreset640x480; 

    [newCaptureSession commitConfiguration]; 
    if ([newCaptureSession canAddInput:newVideoInput]) { 
     [newCaptureSession addInput:newVideoInput]; 
    } 
    if ([newCaptureSession canAddOutput:newStillImageOutput]) { 
     [newCaptureSession addOutput:newStillImageOutput]; 
    } 
    self.stillImageOutput = newStillImageOutput; 
    self.videoInput = newVideoInput; 
    self.captureSession = newCaptureSession; 

    [newStillImageOutput release]; 
    [newVideoInput release]; 
    [newCaptureSession release]; 

Phương pháp của tôi để chụp hình ảnh vẫn còn là khá đơn giản và in ra các định hướng đó là AVCaptureVideoOrientationPortrait:

- (void) captureStillImage 
{ 
    AVCaptureConnection *stillImageConnection = [AVCamUtilities connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self stillImageOutput] connections]]; 

    if ([stillImageConnection isVideoOrientationSupported]){ 
     NSLog(@"isVideoOrientationSupported - orientation = %d", orientation); 
     [stillImageConnection setVideoOrientation:orientation]; 
    } 

    [[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:stillImageConnection 
                 completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) { 


                  ALAssetsLibraryWriteImageCompletionBlock completionBlock = ^(NSURL *assetURL, NSError *error) { 
                   if (error) { // HANDLE } 
                  }; 

                   if (imageDataSampleBuffer != NULL) { 

                   CFDictionaryRef exifAttachments = CMGetAttachment(imageDataSampleBuffer, kCGImagePropertyExifDictionary, NULL); 
                   if (exifAttachments) { 
                    NSLog(@"attachements: %@", exifAttachments); 
                   } else { 
                    NSLog(@"no attachments"); 
                   } 
                   self.stillImageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];                 
                   self.stillImage = [UIImage imageWithData:self.stillImageData]; 

                   UIImageWriteToSavedPhotosAlbum(self.stillImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); 
                } 
                  else 
                   completionBlock(nil, error); 

                 }]; 
} 

Vì vậy, các thiết bị hiểu được nó đang ở chế độ chân dung như nó phải được, attachements exif chỉ cho tôi:

PixelXDimension = 640; 
PixelYDimension = 480; 

nên nó dường như biết rằng chúng ta đang ở 640x480 và đó có nghĩa là RxC (rõ ràng ...)

Tuy nhiên, khi tôi gửi ảnh của mình qua email từ ứng dụng Ảnh của Apple, tôi nhận được hình ảnh 480x640 nếu tôi kiểm tra các thuộc tính trong Xem trước. Điều này không có ý nghĩa gì đối với tôi cho đến khi tôi đào sâu hơn vào các thuộc tính hình ảnh để tìm ra hướng hình ảnh được đặt thành "6 (Xoay 90 độ CCW)" Tôi chắc chắn CCW đang truy cập theo chiều kim đồng hồ

Vì vậy, hãy xem hình ảnh trong trình duyệt: http://tonyamoyal.com/stuff/things_that_make_you_go_hmm/photo.JPG Chúng tôi thấy hình ảnh được xoay 90 độ CCW và nó là 640x480.

Tôi thực sự bối rối về hành vi này. Khi tôi chụp ảnh tĩnh 640x480 bằng AVFoundation, tôi mong đợi mặc định không có hướng xoay. Tôi mong đợi một hình ảnh 640x480 được định hướng chính xác khi mắt tôi nhìn thấy hình ảnh trong lớp xem trước. Ai đó có thể giải thích lý do tại sao điều này xảy ra và làm thế nào để cấu hình chụp để khi tôi lưu hình ảnh của tôi đến máy chủ để hiển thị sau trong một lần xem web, nó không được xoay 90 độ CCW?

Trả lời

33

Điều này xảy ra do định hướng được đặt trong siêu dữ liệu của hình ảnh mới đang được thực hiện theo hướng của hệ thống AV tạo ra nó. Bố cục của dữ liệu hình ảnh thực tế tất nhiên khác với định hướng được đề cập trong siêu dữ liệu của bạn. Một số chương trình xem hình ảnh tôn trọng định hướng siêu dữ liệu, một số bỏ qua nó.

Bạn có thể ảnh hưởng đến định hướng siêu dữ liệu của hệ thống AV bằng cách gọi:

AVCaptureConnection *videoConnection = ...; 
if ([videoConnection isVideoOrientationSupported]) 
    [videoConnection setVideoOrientation:AVCaptureVideoOrientationSomething]; 

Bạn có thể ảnh hưởng đến định hướng siêu dữ liệu của một UIImage bằng cách gọi:

UIImage *rotatedImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:1.0f orientation:UIImageOrientationSomething]; 

Nhưng các dữ liệu thực tế từ AVCapture hệ thống sẽ luôn xuất hiện với kích thước rộng hơn như X và chiều hẹp hẹp hơn là Y, và sẽ xuất hiện để được định hướng trong LandscapeLeft.

Nếu bạn muốn dữ liệu thực tế phù hợp với những gì siêu dữ liệu của bạn xác nhận, bạn cần sửa đổi dữ liệu thực tế. Bạn có thể làm điều này bằng cách viết hình ảnh ra một hình ảnh mới bằng cách sử dụng CGContexts và AffineTransforms. Hoặc có cách giải quyết dễ dàng hơn, sử dụng gói UIImage + Resize như được thảo luận here. Và đổi kích thước hình ảnh thành kích thước hiện tại bằng cách gọi:

UIImage *rotatedImage = [image resizedImage:CGSizeMake(image.size.width, image.size.height) interpolationQuality:kCGInterpolationDefault]; 

Điều này sẽ khắc phục định hướng của dữ liệu dưới dạng tác dụng phụ.

Nếu bạn không muốn bao gồm toàn bộ UIImage + Thay đổi kích thước, bạn có thể kiểm tra mã của nó và loại bỏ các phần nơi dữ liệu được chuyển đổi.

+3

Điều này cần phải có nhiều phiếu vượt trội hơn.Cảm ơn bạn đời – Youssef

+0

Giải pháp tuyệt vời !! –

+0

Rất hữu ích, cảm ơn bạn! –