2012-01-10 37 views
12

Tôi đang sử dụng mã nguồn của ai đó để chụp ảnh bằng AVCaptureSession. Tuy nhiên, tôi thấy rằng previewLayer của CaptureSessionManager là shotter sau đó là hình ảnh được chụp cuối cùng. enter image description hereTỷ lệ hình ảnh iPhone được chụp từ AVCaptureSession

Tôi thấy rằng hình ảnh kết quả luôn bằng tỷ lệ 720x1280 = 9: 16. Bây giờ tôi muốn cắt hình ảnh kết quả thành UIImage với tỷ lệ 320: 480 để nó sẽ chỉ chụp phần hiển thị trong previewLayer. Bất kỳ ý tưởng? Cảm ơn rất nhiều.

Câu hỏi có liên quan trong stackoverflow (NO câu trả lời hay chưa): Q1, Q2

Source Code:

- (id)init { 
if ((self = [super init])) { 
    [self setCaptureSession:[[[AVCaptureSession alloc] init] autorelease]]; 
} 
return self; 
} 

- (void)addVideoPreviewLayer { 
[self setPreviewLayer:[[[AVCaptureVideoPreviewLayer alloc] initWithSession:[self captureSession]] autorelease]]; 
[[self previewLayer] setVideoGravity:AVLayerVideoGravityResizeAspectFill]; 

} 

- (void)addVideoInput { 
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
if (videoDevice) { 
    NSError *error; 


    if ([videoDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus] && [videoDevice lockForConfiguration:&error]) { 
     [videoDevice setFocusMode:AVCaptureFocusModeContinuousAutoFocus]; 
     [videoDevice unlockForConfiguration]; 
    }   

    AVCaptureDeviceInput *videoIn = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error]; 
    if (!error) { 
     if ([[self captureSession] canAddInput:videoIn]) 
      [[self captureSession] addInput:videoIn]; 
     else 
      NSLog(@"Couldn't add video input");  
    } 
    else 
     NSLog(@"Couldn't create video input"); 
} 
else 
    NSLog(@"Couldn't create video capture device"); 
} 

- (void)addStillImageOutput 
{ 
    [self setStillImageOutput:[[[AVCaptureStillImageOutput alloc] init] autorelease]]; 
    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil]; 
    [[self stillImageOutput] setOutputSettings:outputSettings]; 

    AVCaptureConnection *videoConnection = nil; 
    for (AVCaptureConnection *connection in [[self stillImageOutput] connections]) { 
    for (AVCaptureInputPort *port in [connection inputPorts]) { 
     if ([[port mediaType] isEqual:AVMediaTypeVideo]) { 
     videoConnection = connection; 
     break; 
     } 
    } 
    if (videoConnection) { 
     break; 
    } 
    } 

    [[self captureSession] addOutput:[self stillImageOutput]]; 
} 

- (void)captureStillImage 
{ 
AVCaptureConnection *videoConnection = nil; 
for (AVCaptureConnection *connection in [[self 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: %@", [self stillImageOutput]); 
[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection 
                completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) { 
                CFDictionaryRef exifAttachments = CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, NULL); 
                if (exifAttachments) { 
                 NSLog(@"attachements: %@", exifAttachments); 
                } else { 
                 NSLog(@"no attachments"); 
                } 
                NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];  
                UIImage *image = [[UIImage alloc] initWithData:imageData]; 
                [self setStillImage:image]; 
                [image release]; 
                [[NSNotificationCenter defaultCenter] postNotificationName:kImageCapturedSuccessfully object:nil]; 
                }]; 
} 


Chỉnh sửa sau khi làm một số nghiên cứu thêm và thử nghiệm: Thuộc tính của AVCaptureSession "sessionPreset" có các hằng số sau, tôi có không kiểm tra từng người trong số họ, nhưng lưu ý rằng hầu hết trong số họ tỷ lệ là 9:16 hoặc 3: 4,

  • NSString * const AVCaptureSessionPresetPhoto;
  • NSString * const AVCaptureSessionPresetHigh;
  • NSString * const AVCaptureSessionPresetMedium;
  • NSString * const AVCaptureSessionPresetLow;
  • NSString * const AVCaptureSessionPreset352x288;
  • NSString * const AVCaptureSessionPreset640x480;
  • NSString * const AVCaptureSessionPresetiFrame960x540;
  • NSString * const AVCaptureSessionPreset1280x720;
  • NSString * const AVCaptureSessionPresetiFrame1280x720;

Trong dự án của tôi, tôi có xem trước toàn màn hình (kích thước khung hình là 320x480) thêm: [[tự previewLayer] setVideoGravity: AVLayerVideoGravityResizeAspectFill];

Tôi đã thực hiện theo cách này: chụp ảnh ở kích thước 9:16 và cắt ảnh thành 320: 480, chính xác phần hiển thị của previewlayer. Nó thật hoàn hảo.

Các đoạn mã cho thay đổi kích thước và croping để thay thế với mã cũ là camera

NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer]; 
UIImage *image = [UIImage imageWithData:imageData]; 
UIImage *scaledimage=[ImageHelper scaleAndRotateImage:image]; 
//going to crop the image 9:16 to 2:3;with Width fixed 
float width=scaledimage.size.width; 
float height=scaledimage.size.height; 
float top_adjust=(height-width*3/2.0)/2.0; 
[self setStillImage:[scaledimage croppedImage:rectToCrop]]; 
+0

Tại sao bạn không sử dụng 4: 3-sessionPreset, bạn không phải cắt và sử dụng toàn bộ cảm biến máy ảnh? –

Trả lời

28

iPhone có tỉ lệ 4: 3. Hình ảnh 16: 9 bạn nhận được đã bị cắt từ 4: 3. Cắt xén những hình ảnh 16: 9 lại thành 4: 3 không phải là thứ bạn muốn. Thay vào đó hãy lấy hình ảnh gốc 4: 3 từ máy ảnh của iPhone bằng cách đặt self.captureSession.sessionPreset = AVCaptureSessionPresetPhoto (trước khi thêm bất kỳ đầu vào/đầu ra nào cho phiên).

+1

Dominik, Cảm ơn bạn đã trả lời. Ứng dụng iPhone Camera có thanh công cụ ở dưới cùng, tỷ lệ xem trước là (480-44): 320 ~ = 4: 3 = 1.3333, mở trong ứng dụng album, trông giống như đối tượng 480: 320 = 1,50, vì vậy thực tế hình ảnh bị méo đã đúng? nhưng vì 1,333 không khác nhiều so với 1.50, do đó, không quá rõ ràng đối với người dùng –

+0

Có, ứng dụng album ban đầu cắt ảnh ngay lập tức (khía cạnh để lấp đầy, không bị méo) để lấp đầy toàn bộ màn hình. Nhưng với cử chỉ nhéo, bạn có thể thấy toàn bộ hình ảnh 4: 3. –

+0

Cảm ơn bạn giải quyết vấn đề của tôi – Naresh

Các vấn đề liên quan