2013-09-25 1 views
1

메신저는 AVFoundation에 대한 도움을 찾고 있습니다. 현재이 주제에서 정지 이미지를 캡처하는 방법에 대한 단계별 가이드를 따라 왔습니다. How to save photos taken using AVFoundation to Photo Album?어떻게 AVCaptureSessionPreset을 사용할 때 화질을 변경할 수 있습니까?

제 질문은 어떻게 AVCaptureSessionPreset640x480을 사용하여 저장된 이미지의 품질을 낮출 수 있습니까? 나는 화질의 절반을 원한다. 또는 저장된 이미지를 가능한 한 작은 파일로 만들 수있는 또 다른 방법이 있다면 (아마도 320x280), 그러면 실제 품질을 조정하는 것보다 낫을 수있다.

다른 사람이 이전에 물어 본 적이 있는지 알지 못하지만 지난 며칠 동안 웹을 검색해 본 결과 답변을 찾을 수 없습니다. 아래는 제 코드입니다.

#import "ViewController.h" 
#import <ImageIO/ImageIO.h> 

@interface ViewController() 

@end 

@implementation ViewController 

@synthesize imagePreview; 
@synthesize iImage; 
@synthesize stillImageOutput; 

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

     NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer]; 
     //NSData *data2 = [NSData dataWithData:UIImageJPEGRepresentation(image, 0.5f)]]; 
     UIImage *image = [[UIImage alloc] initWithData:imageData]; 

     self.iImage.image = image; 

     UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); 
    }]; 
} 

-(void)viewDidAppear:(BOOL)animated 
{ 
    AVCaptureSession *session = [[AVCaptureSession alloc] init]; 
    session.sessionPreset = AVCaptureSessionPreset640x480; 

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

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

    captureVideoPreviewLayer.frame = self.imagePreview.bounds; 
    [self.imagePreview.layer addSublayer:captureVideoPreviewLayer]; 

    AVCaptureDevice *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]; 

    [session startRunning]; 
} 


- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

@end 

`

`

답변

3

당신에게 다른 해상도의 이미지를 줄 것이다 다른 프리셋을 사용해보십시오.

Apple 설명서에 따라 iPhone4 (뒤로)에 해당 세션에 대한 다음 프리셋에 대한 다음 해상도 이미지가 표시됩니다.

AVCaptureSessionPresetHigh : 1280x720

AVCaptureSessionPresetMedium : 480x360

AVCaptureSessionPresetLow : 192x144

AVCaptureSessionPreset640x480 : 640x480

AVCaptureSessionPreset1280x720 : 1280x720

AVCaptureSessionPresetPhoto : 2592x1936.This is not supported for video output

,536,

희망이 도움이 될 것입니다.

+0

도움을 주셔서 감사합니다. 이미 AVCaptureSessionPreset640x480을 사용하고 있는데, 이는 약 84kb의 파일 크기를 제공하고 있습니다. 저는 이미지를 웹 서비스에 보내서 확인하고 필요로하는 절반 크기를 찾고 있습니다. 처리 시간은 가능한 한 작아야합니다. – Fernando

+0

이미지의 크기에 대해서는 시도하지 않았지만이 이미지를 시도해 볼 수 있습니다. [image resizedImage : CGSizeMake (width, height) interpolationQuality : kCGInterpolationLow]; 이것을 사용하여 이미지 및 품질의 크기를 설정할 수 있습니다. 보간 품질에 대한 기타 옵션은 kCGInterpolationMedium, kCGInterpolationHigh, kCGInterpolationNone입니다. – Apoorv

+0

이 코드를 사용해 보겠습니다. UIImageJPEGRepresentation (image, 1.0f) 품질을 변경합니다 (1.0f는 100 %이므로 50 %를 원한다면 0.5f가됩니다).하지만 avfoundation을 사용하여 구현하는 방법을 잘 모르겠습니다. – Fernando

2

AVCaptureStillImageOutput 개체의 kCVPixelBufferWidthKeykCVPixelBufferHeightKey 옵션을 선택하여 해상도를 설정해야합니다. 이 너비/높이는 세션 미리 설정된 너비/높이를 재정의합니다. 아래의 최소 샘플 (에러 체크 추가).

_session = [[AVCaptureSession alloc] init]; 
    _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 

    NSError * error; 
    _sessionInput = [AVCaptureDeviceInput deviceInputWithDevice:_device error:&error]; 
    _stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; 
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
           [NSNumber numberWithDouble:320.0], (id)kCVPixelBufferWidthKey, 
           [NSNumber numberWithDouble:280.0], (id)kCVPixelBufferHeightKey, 
           [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], (id)kCVPixelBufferPixelFormatTypeKey, 
           nil]; 

    [_stillImageOutput setOutputSettings:options]; 

    [_session beginConfiguration ]; 
    [_session addInput:_sessionInput]; 
    [_session addOutput:_stillImageOutput]; 
    [_session setSessionPreset:AVCaptureSessionPresetPhoto]; 
    _avConnection = [_stillImageOutput connectionWithMediaType:AVMediaTypeVideo]; 
    [ _session commitConfiguration ]; 

............. 

- (void) start 
{ 
    [self.session startRunning]; 
} 

............. 

[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:self.avConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) 
{ 
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(imageSampleBuffer); 
    CVPixelBufferLockBaseAddress(imageBuffer, 0); 
    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 
    NSLog(@"%d : %d", height, width); 

}]; 

참고 : 저는 이것을 Mac에서만 시도했습니다. 이상적으로 iOS에서도 작동해야합니다. 또한 일부 종횡비를 유지하십시오.

관련 문제