web-dev-qa-db-ja.com

コントロールを表示せずにiPhoneで写真を撮る

Appleコントロールを経由せずにiPhoneのコードで写真を撮る方法はありますか?これを行うアプリをたくさん見ましたが、どのAPI呼び出しが行われるのかわかりません使用する。

22
Rob Bonner

はい、これを行うには2つの方法があります。 iOS 3.0以降で利用できる1つは、UIImagePickerControllerクラスを使用し、showsCameraControlsプロパティをNOに設定し、cameraOverlayViewプロパティを独自のカスタムコントロールに設定することです。 2つは、iOS 4.0以降で利用可能で、AVCaptureSessionを構成し、適切なカメラデバイスを使用してAVCaptureDeviceInputを提供し、AVCaptureStillImageOutputを提供します。最初のアプローチははるかに単純で、より多くのiOSバージョンで機能しますが、2番目のアプローチでは、写真の解像度とファイルオプションをより細かく制御できます。

25
Drew C

編集:以下のコメントで示唆されているように、AVCaptureSessionを宣言して初期化する方法を明示的に示しました。初期化を間違えたり、メソッド内のローカル変数としてAVCaptureSessionを宣言したりしている人もいるようです。これは機能しません。

次のコードを使用すると、ユーザー入力なしでAVCaptureSessionを使用して写真を撮ることができます。

// Get all cameras in the application and find the frontal camera.
AVCaptureDevice *frontalCamera;
NSArray *allCameras = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];

// Find the frontal camera.
for ( int i = 0; i < allCameras.count; i++ ) {
    AVCaptureDevice *camera = [allCameras objectAtIndex:i];

    if ( camera.position == AVCaptureDevicePositionFront ) {
        frontalCamera = camera;
    }
}

// If we did not find the camera then do not take picture.
if ( frontalCamera != nil ) {
    // Start the process of getting a picture.
    session = [[AVCaptureSession alloc] init];

    // Setup instance of input with frontal camera and add to session.
    NSError *error;
    AVCaptureDeviceInput *input =
    [AVCaptureDeviceInput deviceInputWithDevice:frontalCamera error:&error];

    if ( !error && [session canAddInput:input] ) {
        // Add frontal camera to this session.
        [session addInput:input];

        // We need to capture still image.
        AVCaptureStillImageOutput *output = [[AVCaptureStillImageOutput alloc] init];

        // Captured image. settings.
        [output setOutputSettings:
        [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil]];

        if ( [session canAddOutput:output] ) {
            [session addOutput:output];

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

            // Finally take the picture
            if ( videoConnection ) {
                [session startRunning];

                [output captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {

                    if (imageDataSampleBuffer != NULL) {
                        NSData *imageData = [AVCaptureStillImageOutput 
                                  jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
                        UIImage *photo = [[UIImage alloc] initWithData:imageData];                                                                 
                    }

                }];
            }
        }
    }
}

セッション変数はAVCaptureSession型であり、クラスの.hファイルで(プロパティまたはクラスのプライベートメンバーとして)宣言されています。

AVCaptureSession *session;

次に、たとえばクラスのinitメソッドのどこかで初期化する必要があります。

session = [[AVCaptureSession alloc] init]
37
Khurram Ali