1

AVFoundation のヘルプを探しています。現在、このトピックから静止画像をキャプチャする方法に関するステップバイステップガイドに従っています: AVFoundation を使用して撮影した写真をフォト アルバムに保存する方法は?

私の質問は、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

`

4

2 に答える 2

3

異なる解像度の画像を提供する別のプリセットを使用してみてください。

Apple ドキュメントによると、iPhone4(Back) の場合、そのセッションの次のプリセットの次の解像度の画像が得られます。

AVCaptureSessionPresetHigh : 1280x720

AVCaptureSessionPresetMedium : 480x360

AVCaptureSessionPresetLow : 192x144

AVCaptureSessionPreset640x480 : 640x480

AVCaptureSessionPreset1280x720 : 1280x720

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

これが役立つことを願っています。

于 2013-09-25T10:58:28.060 に答える
2

選択した解像度を設定するには、オブジェクトにkCVPixelBufferWidthKeyオプションkCVPixelBufferHeightKeyを設定する必要があります。AVCaptureStillImageOutputこの幅/高さは、セッション プリセットの幅/高さを上書きします。以下のような最小限のサンプル (エラー チェックを追加)。

    _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 でも機能するはずです。また、アスペクト比を維持してみてください。

于 2014-05-23T04:58:03.703 に答える