こんばんは。swiftUIを使用してシンプルなカメラアプリを開発しています。
シャッターボタンを押した時に写真を取り、それを写真フォルダに保存したいです。
swift
1import Foundation 2import AVFoundation 3import UIKit 4import Combine 5 6class CameraController: NSObject{ 7 8 // デバイスからの入力と出力を管理するオブジェクトの作成 9 var captureSession = AVCaptureSession() 10 11 // カメラの画質の設定 12 func setupCaptureSession() { 13 captureSession.sessionPreset = AVCaptureSession.Preset.photo 14 } 15 16 // カメラデバイスそのものを管理するオブジェクトの作成 17 // メインカメラの管理オブジェクトの作成 18 var mainCamera: AVCaptureDevice? 19 // インカメの管理オブジェクトの作成 20 var innerCamera: AVCaptureDevice? 21 // 現在使用しているカメラデバイスの管理オブジェクトの作成 22 var currentDevice: AVCaptureDevice? 23 24 // デバイスの設定 25 func setupDevice() { 26 // カメラデバイスのプロパティ設定 27 let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified) 28 // プロパティの条件を満たしたカメラデバイスの取得 29 let devices = deviceDiscoverySession.devices 30 31 for device in devices { 32 if device.position == AVCaptureDevice.Position.back { 33 mainCamera = device 34 } else if device.position == AVCaptureDevice.Position.front { 35 innerCamera = device 36 } 37 } 38 // 起動時のカメラを設定 39 currentDevice = mainCamera 40 } 41 42 43 // キャプチャーの出力データを受け付けるオブジェクト 44 var photoOutput = AVCapturePhotoOutput() 45 46 // 入出力データの設定 47 func setupInputOutput() { 48 do { 49 // 指定したデバイスを使用するために入力を初期化 50 let captureDeviceInput = try AVCaptureDeviceInput(device: currentDevice!) 51 // 指定した入力をセッションに追加 52 captureSession.addInput(captureDeviceInput) 53 // 出力データを受け取るオブジェクトの作成 54 photoOutput = AVCapturePhotoOutput() 55 // 出力ファイルのフォーマットを指定 56 photoOutput.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey : AVVideoCodecType.jpeg])], completionHandler: nil) 57 captureSession.addOutput(photoOutput) 58 } catch { 59 print(error) 60 } 61 } 62 63 // プレビュー表示用のレイヤ 64 var cameraPreviewLayer : AVCaptureVideoPreviewLayer? 65 66 // カメラのプレビューを表示するレイヤの設定 67 func setupPreviewLayer() { 68 // 指定したAVCaptureSessionでプレビューレイヤを初期化 69 self.cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 70 // プレビューレイヤが、カメラのキャプチャーを縦横比を維持した状態で、表示するように設定 71 self.cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill 72 // プレビューレイヤの表示の向きを設定 73 self.cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait 74 } 75 76 override init() { 77 super.init() 78 setupCaptureSession() 79 setupDevice() 80 setupInputOutput() 81 setupPreviewLayer() 82 captureSession.startRunning() 83 } 84 85 func cameraButton_TouchUpInside(_ sender: Any) { 86 let settings = AVCapturePhotoSettings() 87 // フラッシュの設定 88 89 settings.flashMode = .auto 90 // 撮影された画像をdelegateメソッドで処理 91 self.photoOutput.capturePhoto(with: settings, delegate: self as AVCapturePhotoCaptureDelegate) 92 } 93} 94 95extension CameraController: AVCapturePhotoCaptureDelegate{ 96 func photoOutput(_ output: AVCapturePhotoOutput, 97 didFinishProcessingPhoto photo: AVCapturePhoto, 98 error: Error?){ 99 if let imageData = photo.fileDataRepresentation() { 100 // Data型をUIImageオブジェクトに変換 101 let uiImage = UIImage(data: imageData) 102 // 写真ライブラリに画像を保存 103 UIImageWriteToSavedPhotosAlbum(uiImage!, nil,nil,nil) 104 } 105 } 106} 107
こちらが実際のカメラの設定ファイルです。
ContentViewで、
swift
1Button(action: { 2 //シャッター 3 CameraController().cameraButton_TouchUpInside(self) 4 print("Round Action") 5}) { 6 Circle() 7 .fill(Color.black) 8 .frame(width: UIScreen.screenWidth/6, height: UIScreen.screenWidth/6) 9 .shadow(radius: 10) 10}
を呼んでいます。 しかし、cameraButton_TouchUpInside(self)
は呼ばれているのですが、photoOutput
は呼ばれていませんでした。
お手隙の際に何を修正すればいいのかご教示くだされば幸いです。
回答者さまにご指摘いただきましたが、不勉強故に出典のリンクを貼るのを忘れていました。申し訳ありません。
今回参考にさせていただきました記事:
Swiftでカメラアプリを作成する(1)
Swiftでカメラアプリを作成する(2)
よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/17 02:07