AVFoundation을 사용하여 촬영 응용 프로그램 개발


나는 AVFoundation을 이용하여 촬영 응용을 개발하는 방법을 썼다.사과 어려워 보이지만 사진 촬영 기능만 있다면 적은 코드로 기능을 구현할 수 있다.본 글의 견본 코드는 아래에 놓으세요.
https://github.com/NAOYA-MAEDA-DEV/AVFoundation-Camera-App

방문권 확인


응용 프로그램에서 카메라, 마이크 등 아이폰 기기, 사진 라이브러리와 연락처 등 사용자 데이터에 접근할 때 인포에 주의하십시오.plist에 대한 편집과 접근권 확인 처리를 코드로 기술해야 합니다.

Info.plist 편집


Info.plist에 필요한 접근권과 접근 이유를 기록합니다.포토 기능은 아이폰의 카메라로 촬영한 사진을 포토라이브러리에 저장하는 것이어서 다음과 같은 접근권이 필요하다.
  • 아이폰의 카메라 접근권(Prevacy-Cammera Usage Description)
  • Privacy-Photo Library Usage Description

  • 방문권 확인


    앱에서 아이폰의 기기와 사용자 데이터에 접근할 때는 사전에 접근권을 확인해야 한다.다음 코드는 아이폰 카메라와 포토라이브러리 접근권을 확인하는 경보를 보여 준다.
    CameraViewController.swift
    private func checkPermission() {
        // カメラ
        switch AVCaptureDevice.authorizationStatus(for: .video) {
        case .authorized:
            break
        case .notDetermined:
            AVCaptureDevice.requestAccess(for: .video, completionHandler: { granted in
                if !granted {
                  self.setupResult = .notAuthorized
                }
            })
        default:
            self.setupResult = .notAuthorized
            break
        }
        // フォトライブラリ
        switch PHPhotoLibrary.authorizationStatus() {
        case .authorized:
            break
        case .notDetermined:
            PHPhotoLibrary.requestAuthorization({ photoAuthStatus in
                if photoAuthStatus ==  PHAuthorizationStatus.authorized {
                }
            })
        default :
            break
        }
    }
    

    카메라 설정 및 카메라 이미지 디스플레이


    카메라의 설정과 카메라의 영상을 표시하는 데 필요한 설정 항목은 다음과 같은 7개다.
  • 아이폰의 백카메라AVCaptureDevice
  • 가져오기

  • 사용AVCaptureDevice생성AVCaptureDeviceInput
  • AVCaptureSession에서 설정AVCaptureDeviceInput
  • AVCaptureSession에서 설정AVCaptureOutputAVCapturePhotoOutput
  • AVCaptureSession로 생성된 카메라 이미지의 미리보기 레이어AVCaptureVideoPreviewLayer를 카메라 영상을 표시하려는 View
  • 에 설정합니다.

  • 설정AVCaptureSessionsessionPreset에 표시되는 이미지 품질

  • 실행 AVCaptureSessionstartRunning()
  • AVCaptureDevice는 입력장치(카메라, 마이크 등)를 나타내는 클래스, AVCaptureDeviceInput는 입력장치의 입력원을 나타내는 클래스, AVCaptureOutput는 출력 유형(사진, 영화 등)을 나타내는 클래스다.AVCaptureSession는 입력원과 출력 유형을 연결하는 중계소 역할을 하는 반이다.sessionPreset는 영상의 질을 지정하는 학급이다.AVCaptureVideoPreviewLayer는 카메라의 영상을 표시하는 등급이다.startRunning()는 입력원에서 출력 형식으로 데이터 흐름을 시작하는 방법입니다.위 1-7을 수행하여 다음 그림과 같은 프로세스를 만듭니다.

    다음 코드는 아이폰의 백카메라AVCaptureDevice를 취득하고 아이폰의 백카메라AVCaptureDevice에서 입력원AVCaptureDeviceInput을 생성한다.AVCaptureSession 생성된 입력 원본을 설정하고 출력 유형을 사진 출력AVCapturePhotoOutput으로 설정하며 카메라 이미지의 미리보기 층AVCaptureVideoPreviewLayerpreviewImageView에 설정합니다.영상의 품질은 표준 카메라 앱을 사용해 사진을 찍을 때와 같기 때문에 사전 설정AVCaptureSession.Preset.photo을 설정했다.
    CameraViewController.swift
    private func configureSession() {
        guard setupResult == .success else {
            return
        }
        self.captureSession.beginConfiguration() // 入力と出力変更を行う前に実行
        do {
            var defaultVideoDevice: AVCaptureDevice?
    	// 1. iPhoneのバックカメラ(AVCaptureDevice)を取得
            if let backCameraDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) {
                defaultVideoDevice = backCameraDevice
            }
            guard let videoDevice = defaultVideoDevice else {
                return
            }
    	// 2. AVCaptureDeviceを使用してAVCaptureDeviceInputを生成
            let input = try AVCaptureDeviceInput(device: videoDevice)
            if self.captureSession.canAddInput(input) {
    	   // 3. AVCaptureSessionにAVCaptureDeviceInputをセット
                self.captureSession.addInput(input)
                // 4. AVCaptureSessionにAVCaptureOutputをセット
                if self.captureSession.canAddOutput(self.photoOutput) {
                    self.captureSession.addOutput(self.photoOutput)
    		// 5. AVCaptureSessionを使用して生成したカメラ映像のプレビューレイヤーをカメラ映像を表示したいViewにセット
                    self.captureVideoLayer = AVCaptureVideoPreviewLayer.init(session: self.captureSession)
                    self.captureVideoLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
                    DispatchQueue.main.async {
                        self.captureVideoLayer.frame = self.previewImageView.bounds
                        self.previewImageView.contentMode = .scaleAspectFill
                        self.previewImageView.layer.addSublayer(self.captureVideoLayer)
                    }
                }
    	    // 6. AVCaptureSessionのsessionPresetに表示する映像の品質をセット
                self.captureSession.sessionPreset = AVCaptureSession.Preset.photo
            }
        } catch {
            return
        }
        captureSession.commitConfiguration() // 入力と出力変更後に必ず実行
    }
    // 7. AVCaptureSessionのstartRunning()を実行
    captureSession.startRunning()
    
    변경AVCaptureSession의 입력과 출력은 변경 전beginConfiguration(), 변경이 완료된 후commitConfiguration()에 실행해야 한다.

    사진을 찍기 시작하다


    집행AVCapturePhotoOutputcapturePhoto방법을 통해 촬영을 시작하다.capturePhoto 방법의 매개 변수에 촬영 시작부터 끝날 때까지 호출된 경계부호 방법의 의뢰자와 촬영한 사진의 옵션 정보를 저장하는 대상AVCapturePhotoSettings을 지정한다.양도인 지정self은 다음과 같은 코드ViewController를 기술했다.AVCapturePhotoSettings 대상을 수정해 사진이 저장된 형식과 메타데이터를 수정할 수 있지만 사진만 찍는다면 특별히 수정할 필요가 없다.
    CameraViewController.swift
    self.settingsForMonitoring = AVCapturePhotoSettings()
    self.photoOutput.capturePhoto(with: self.settingsForMonitoring, delegate: self)
    

    촬영 시 사용하는 경계부호 방법


    촬영부터 끝까지 몇 가지 경계선 방법을 사용하지만 사용하는 경계선 방법은 다음과 같은 두 가지가 있다.
  • photoOutput(_:didFinishProcessingPhoto:error:)
  • photoOutput(_:didFinishCaptureFor:error:)
  • 전항은 델리멘의 양도지self를 지정했다.ViewController에 상기 델리멘 방법을 기술하기 위해 양도인ViewController은 반드시 AVCapturePhotoCaptureDelegate 협의를 준수해야 한다.
    CameraViewController.swift
    final class CameraViewController: UIViewController, AVCapturePhotoCaptureDelegate
    

    사진 처리


    사진 출력 완료


    사진 출력이 완성된 시간photoOutput(_:didFinishProcessingPhoto:error:) 호출 방법.파라미터photo는 촬영한 사진 데이터다.photo의 유형은 AVCapturePhoto이므로 사진 라이브러리에 저장할 수 없습니다.따라서 fileDataRepresentation() 사용 방법을 통해 사진 라이브러리에 저장할 수 있다Data?.사진을 저장할 때 이 Data? 유형의 대상이 필요하기 때문에 변수로 저장합니다.
    CameraViewController.swift
    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
        guard error == nil else {
            print("Error broken photo data: \(error!)")
            return
        }
        guard let photoData = photo.fileDataRepresentation() else {
            print("No photo data to write.")
            return
        }
        self.compressedData = photoData // 保持
    }
    

    사진 저장


    촬영에 필요한 일련의 처리가 모두 완성된 시간photoOutput(_:didFinishCaptureFor:error:) 호출 방법.photoOutput(_:didFinishProcessingPhoto:error:) 방법에 저장된 Data?형 대상을 사진 데이터로 하고 PHPhotoLibrary.shared().performChanges 방법으로 사진 라이브러리에 저장한다.
    CameraViewController.swift
    func photoOutput(_ output: AVCapturePhotoOutput,
                     didFinishCaptureFor resolvedSettings: AVCaptureResolvedPhotoSettings,
                     error: Error?) {  
        guard error == nil else {
            print("Error capture photo: \(error!)")
            return
        }
        guard let compressedData = self.compressedData else {
            print("The expected photo data isn't available.")
            return
        }
        PHPhotoLibrary.requestAuthorization(for: .addOnly) { status in
            guard status == .authorized else { return }
            PHPhotoLibrary.shared().performChanges {
                let creationRequest = PHAssetCreationRequest.forAsset()
                creationRequest.addResource(with: .photo, data: compressedData, options: nil)
            } completionHandler: { success, error in
                if let _ = error {
                    print("Error save photo: \(error!)")
                }
            }
        }
    }
    
    이상 사진 촬영 기능의 설치가 완료되었습니다.다음번 영상 촬영 기능을 해설하다.

    좋은 웹페이지 즐겨찾기