【问题标题】:How Can i change image quality when using AVCaptureSessionPreset使用 AVCaptureSessionPreset 时如何更改图像质量
【发布时间】:2014-05-23 13:15:45
【问题描述】:

我正在寻找有关 AVFoundation 的帮助。目前我有一个关于如何从这个主题捕获静止图像的分步指南:How to save photos taken using AVFoundation to Photo Album?

我的问题是,如何降低保存图像的质量以及使用 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

`

【问题讨论】:

    标签: ios objective-c image avfoundation avcapturesession


    【解决方案1】:

    尝试使用不同的预设,这将为您提供不同分辨率的图像。

    根据 Apple 文档,对于 iPhone4(背面),您将获得该会话的以下预设的以下分辨率图像。

    AVCaptureSessionPresetHigh : 1280x720

    AVCaptureSessionPresetMedium : 480x360

    AVCaptureSessionPresetLow : 192x144

    AVCaptureSessionPreset640x480 : 640x480

    AVCaptureSessionPreset1280x720 : 1280x720

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

    希望这会有所帮助。

    【讨论】:

    • 感谢您的帮助,我已经在使用 AVCaptureSessionPreset640x480,它给了我大约 84kb 的文件大小,我正在寻找一半的大小,因为我会将图像发送到网络服务检查,我需要它尽可能小,以便处理时间。
    • 图片大小我没试过,但是你可以试试这个图片= [image resizedImage:CGSizeMake(width, height) interpolationQuality:kCGInterpolationLow];使用它您可以设置图像的大小和质量。interpolationQuality 的其他选项是 kCGInterpolationMedium、kCGInterpolationHigh、kCGInterpolationNone
    • 我会试试看,但我有这样的代码:UIImageJPEGRepresentation(image, 1.0f) 之前使用它会改变质量(1.0f 是 100%,所以如果我想要 50% 它将是 0.5f) 但我不确定如何使用 avfoundation 来实现它。
    • 每当你得到 NSData 到 UIImage 然后写上面一行 UIIMageJPEGRepresentaion..
    【解决方案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。还可以尝试保持一定的纵横比。

    【讨论】:

      猜你喜欢
      • 2019-09-19
      • 1970-01-01
      • 1970-01-01
      • 2016-10-24
      • 2012-09-15
      • 1970-01-01
      • 1970-01-01
      • 2014-11-14
      • 1970-01-01
      相关资源
      最近更新 更多