1

私が苦労しているズームにはまだ問題があります。link1link2のコードに従って AVCaptureSession を使用して画像を取得しようとしました。

カメラのズームを実装しようとするとすぐに、思い通りに動作しないことを除いて、すべてが非常にうまく機能します。

以下のコードに見られるように、AVCaptureDevice オブジェクトで videoZoomFactor メソッドを使用しようとしています。

videoZoomFactor が効果がない理由について何か提案はありますか??

意図したとおりに AVCaptureSession を使用して、静止画像を取得するためのズームをどのように作成しますか??

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

        // SOMEHOW NOT HAVING AN EFFECT AT ALL - WHY ?????
        if ([videoDevice lockForConfiguration:nil]) {
            float zoomFactor = videoDevice.activeFormat.videoZoomFactorUpscaleThreshold;
            [videoDevice setVideoZoomFactor:zoomFactor];
            // [videoDevice setVideoZoomFactor:3];
            // videoDevice.videoZoomFactor = 3;
            [videoDevice unlockForConfiguration];
        }

        // that all works again nicely...
        NSError *error;
        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");
}
4

2 に答える 2

3

すべての形式がズームをサポートしているわけではありません。現在のフォーマットを印刷する場合

NSLog(@"Current format: %@, max zoom factor: %f", videoDevice.activeFormat, videoDevice.activeFormat.videoMaxZoomFactor);

おそらく次のような結果が得られます (ズーム レベルなし)。

Current format: <AVCaptureDeviceFormat: 0x1559b3a0 'vide'/'420v' 1280x 720, { 1- 30 fps}, fov:49.240>, max zoom level: 1.000000

次に、すべての形式を印刷する場合

NSLog(@"All formats: %@", videoDevice.formats);

ズーム倍率を持っているものと持っていないものがあることに気付くでしょう

All formats: (
    "<AVCaptureDeviceFormat: 0x1556aef0 'vide'/'420v'  192x 144, { 1- 30 fps}, fov:64.000, binned>",
    "<AVCaptureDeviceFormat: 0x1556f4e0 'vide'/'420f'  192x 144, { 1- 30 fps}, fov:64.000, binned>",
    "<AVCaptureDeviceFormat: 0x1556f3e0 'vide'/'420v'  352x 288, { 1- 30 fps}, fov:61.260, binned>",
    "<AVCaptureDeviceFormat: 0x1556f3f0 'vide'/'420f'  352x 288, { 1- 30 fps}, fov:61.260, binned>",
    "<AVCaptureDeviceFormat: 0x1556f360 'vide'/'420v'  480x 360, { 1- 30 fps}, fov:64.000, binned>",
    "<AVCaptureDeviceFormat: 0x1556f370 'vide'/'420f'  480x 360, { 1- 30 fps}, fov:64.000, binned>",
    "<AVCaptureDeviceFormat: 0x1556ae30 'vide'/'420v'  640x 480, { 1- 30 fps}, fov:64.000, binned>",
    "<AVCaptureDeviceFormat: 0x1556ae40 'vide'/'420f'  640x 480, { 1- 30 fps}, fov:64.000, binned>",
    "<AVCaptureDeviceFormat: 0x1556f5c0 'vide'/'420v'  960x 540, { 1- 30 fps}, fov:58.460, binned>",
    "<AVCaptureDeviceFormat: 0x1556f5d0 'vide'/'420f'  960x 540, { 1- 30 fps}, fov:58.460, binned>",
    "<AVCaptureDeviceFormat: 0x1556f3a0 'vide'/'420v' 1280x 720, { 1- 30 fps}, fov:49.240>",
    "<AVCaptureDeviceFormat: 0x1556f3b0 'vide'/'420f' 1280x 720, { 1- 30 fps}, fov:49.240>",
    "<AVCaptureDeviceFormat: 0x1556aa60 'vide'/'420v' 2592x1936, { 1- 15 fps}, fov:64.000, max zoom:121.00 (upscales @1.00)>",
    "<AVCaptureDeviceFormat: 0x1556aa70 'vide'/'420f' 2592x1936, { 1- 15 fps}, fov:64.000, max zoom:121.00 (upscales @1.00)>"

私の場合、最後の2つは最大ズームです。この場合、activeFormat を最後のもの (最大ズームが 1 より大きい (1 = ズームなし)) に設定しています。私の例 (lastObject) のようにとるべきではありません。最初に、ズームが 1 より大きいフォーマットを確認する必要があります。

videoDevice.activeFormat = [videoDevice.formats lastObject];

1.0 から videoMaxZoomFactor までの任意の数値を設定できるようになりました。

[videoDevice setVideoZoomFactor:5.0];
于 2014-10-15T15:26:37.217 に答える
0

次のコードで動作するようになりました:

dispatch_async(sessionQueue, ^{
    [self setBackgroundRecordingID:UIBackgroundTaskInvalid];

    NSError *error = nil;

    AVCaptureDevice *videoDevice = [iKKAvCamViewController deviceWithMediaType:AVMediaTypeVideo preferringPosition:AVCaptureDevicePositionBack];
    AVCaptureDeviceInput *videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];

    if (error)
    {
        NSLog(@"%@", error);
    }

    if ([session canAddInput:videoDeviceInput])
    {
        [session addInput:videoDeviceInput];
        [self setVideoDeviceInput:videoDeviceInput];

        dispatch_async(dispatch_get_main_queue(), ^{
            // Why are we dispatching this to the main queue?
            // Because AVCaptureVideoPreviewLayer is the backing layer for AVCamPreviewView and UIView can only be manipulated on main thread.
            // Note: As an exception to the above rule, it is not necessary to serialize video orientation changes on the AVCaptureVideoPreviewLayer’s connection with other session manipulation.

            [[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] setVideoOrientation:(AVCaptureVideoOrientation)[self interfaceOrientation]];

            // Apply initial VideoZoomFactor to the device
            NSNumber *DefaultZoomFactor = [[NSNumber alloc] initWithFloat:3.0];
            NSError *error = nil;
            if ([[[self videoDeviceInput] device] lockForConfiguration:&error])
            {
                [[[self videoDeviceInput] device] setVideoZoomFactor:[DefaultZoomFactor floatValue]];
                self.zoomFactorLabel.text = [NSString stringWithFormat:@"%.1f", [DefaultZoomFactor floatValue]];
                [[[self videoDeviceInput] device] unlockForConfiguration];
            }
            else
            {
                NSLog(@"%@", error);
            }                
        });
    }
});
于 2014-10-15T17:16:26.847 に答える