質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1327閲覧

Swift AVFoundationで作成したカメラアプリで画像のExif情報を得るやり方がわかりません

maru.wk

総合スコア30

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/11/08 09:25

編集2017/11/09 02:15

AVFoundationを利用し、シャッタースピードを変更できるカメラアプリを作成したのですが、いざその画像をパソコンで開いてみたところ、Exif情報がなく、本当に指定したシャッタースピードにできているか確認できませんでした。
UIImagePickerControllerを使用した場合のExif情報を見れるようにするやり方はわかったのですが、AVFoundationでのやり方は見つけることができませんでした。どうすればAVFoundationでもExif情報を取得できるのでしょうか?

swift

1import UIKit 2import Foundation 3import AVFoundation 4 5class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource{ 6 // プレビュー用のビューとOutlet接続しておく 7 @IBOutlet weak var previewView: UIView! 8 9 // インスタンスの作成 10 var session = AVCaptureSession() 11 var photoOutput = AVCapturePhotoOutput() 12 // 通知センターを作る 13 let notification = NotificationCenter.default 14 15 @IBOutlet weak var myPickerView: UIPickerView! 16 17 override func viewDidLoad() { 18 super.viewDidLoad() 19 // Do any additional setup after loading the view, typically from a nib. 20 21 //myPickerViewのデリゲートになる 22 myPickerView.delegate = self 23 //myPickerViewのデータソースになる 24 myPickerView.dataSource = self 25 26 // セッション実行中ならば中断する 27 if session.isRunning { 28 return 29 } 30 // 入出力の設定 31 setupInputOutput() 32 // プレビューレイヤの設定 33 setPreviewLayer() 34 // セッション開始 35 session.startRunning() 36 // デバイスが回転したときに通知するイベントハンドラを設定する 37 notification.addObserver(self, 38 selector: #selector(self.changedDeviceOrientation(_:)), 39 name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) 40 41 } 42 43 //コンポーネントに表示する項目名 44 let myValue = [["1/4","1/15","1/60","1/250","1/1000"]] 45 //let myValue2 = [["400","200"]] 46 //ピッカービューのコンポーネントの個数を返す 47 func numberOfComponents(in pickerView: UIPickerView) -> Int { 48 return myValue.count 49 } 50 //各コンポーネントの行数を返す 51 func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 52 let compo = myValue[component] 53 return compo.count 54 //if component == 0 { 55 //1個目のピッカーの設定 56 //return CGFloat(myValue.count) 57 //} 58 //return CGFloat(myValue2.count) 59 60 } 61 62 //各コンポーネントの横幅を返す 63 64 //pickerに表示する値を返すデリゲートメソッド 65 func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 66 let item = myValue[component][row] 67 return item 68// if component == 0 { 69// //1個目のピッカーの設定 70// return myValue[row] 71// } 72 // return myValue2[row] 73 74 75 } 76 var ss : Double? 77 func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 78 let item = Double(myValue[component][row]) 79 ss = item 80 81 } 82 // シャッターボタンで実行する 83 @IBAction func takePhoto(_ sender: Any) { 84 let captureSetting = AVCapturePhotoSettings() 85 captureSetting.flashMode = .auto 86 captureSetting.isAutoStillImageStabilizationEnabled = true 87 captureSetting.isHighResolutionPhotoEnabled = false 88 // キャプチャのイメージ処理はデリゲートに任せる 89 photoOutput.capturePhoto(with: captureSetting, delegate: self) 90 } 91 // 入出力の設定 92 func setupInputOutput(){ 93 //解像度の指定 94 session.sessionPreset = AVCaptureSessionPresetPhoto 95 96 // 入力の設定 97 do { 98 //デバイスの取得 99 let device = AVCaptureDevice.defaultDevice( 100 withDeviceType: AVCaptureDeviceType.builtInWideAngleCamera, 101 mediaType: AVMediaTypeVideo, 102 position: .back) 103 104 // 入力元 105 let input = try AVCaptureDeviceInput(device: device) 106 if session.canAddInput(input){ 107 session.addInput(input) 108 } else { 109 print("セッションに入力を追加できなかった") 110 return 111 } 112 } catch let error as NSError { 113 print("カメラがない (error)") 114 return 115 } 116 117 // 出力の設定 118 if session.canAddOutput(photoOutput) { 119 session.addOutput(photoOutput) 120 } else { 121 print("セッションに出力を追加できなかった") 122 return 123 } 124 } 125 126 // プレビューレイヤの設定 127 func setPreviewLayer(){ 128 // プレビューレイヤを作る 129 let previewLayer = AVCaptureVideoPreviewLayer(session: session) 130 guard let videoLayer = previewLayer else { 131 print("プレビューレイヤを作れなかった") 132 return 133 } 134 videoLayer.frame = view.bounds 135 videoLayer.masksToBounds = true 136 videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 137 // previewViewに追加する 138 previewView.layer.addSublayer(videoLayer) 139 } 140 141 // デバイスの向きが変わったときに呼び出すメソッド 142 func changedDeviceOrientation(_ notification :Notification) { 143 // photoOutput.connectionの回転向きをデバイスと合わせる 144 if let photoOutputConnection = self.photoOutput.connection(withMediaType: AVMediaTypeVideo) { 145 switch UIDevice.current.orientation { 146 case .portrait: 147 photoOutputConnection.videoOrientation = .portrait 148 case .portraitUpsideDown: 149 photoOutputConnection.videoOrientation = .portraitUpsideDown 150 case .landscapeLeft: 151 photoOutputConnection.videoOrientation = .landscapeRight 152 case .landscapeRight: 153 photoOutputConnection.videoOrientation = .landscapeLeft 154 default: 155 break 156 } 157 } 158 } 159 160 //ISOとシャッタースピードの処理 161 func ChangeValue(sender: UIPickerView) { 162 let Setting = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) 163 164 do { 165 try Setting?.lockForConfiguration() 166 167 let timerMapping: Float = Float(ss!) 168 let StockTime: Int32 = Int32(timerMapping) 169 let SetTime: CMTime = CMTimeMake(1, StockTime) 170 171 Setting?.setExposureModeCustomWithDuration(SetTime, iso: 100, completionHandler: nil) 172 173 Setting?.unlockForConfiguration() 174 } catch { 175 176 let alertController = UIAlertController(title: "Cheak", message: "False !!", preferredStyle: .alert) 177 178 let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil) 179 alertController.addAction(defaultAction) 180 present(alertController, animated: true, completion: nil) 181 } 182 183 } 184

また、本来であればシャッタースピードを早くするほど画像が暗くなるはずなのですが、暗くなっていないように感じます。pickerViewから正しく値を得れていないような気がするのですが、エラーは出ておりません。申し訳ありませんが、間違っている点があればご指摘お願い致します。

〜追記〜
画像を保存する処理のコードが抜けていたので、追記します。

swift

1import Photos 2 3//デリゲート部分を拡張する 4extension ViewController:AVCapturePhotoCaptureDelegate{ 5 // 映像をキャプチャする 6 func capture(_ captureOutput: AVCapturePhotoOutput, 7 didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, 8 previewPhotoSampleBuffer: CMSampleBuffer?, 9 resolvedSettings: AVCaptureResolvedPhotoSettings, 10 bracketSettings: AVCaptureBracketedStillImageSettings?, 11 error: Error?) { 12 13 14 //バッファからjpegのデータを取り出す 15 let photoData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer!, previewPhotoSampleBuffer: previewPhotoSampleBuffer) 16 //photoDataがnil出ない時UIImageに変換する 17 if let data = photoData { 18 if let stillImage = UIImage(data: data) { 19 UIImageWriteToSavedPhotosAlbum(stillImage, nil, nil, nil) 20 21 22 23 } 24 } 25 } 26}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2017/11/09 01:22

肝心のアルバムに保存するコードが無いような気がするのですが気のせいでしょうか。
maru.wk

2017/11/09 02:15

すみません。載せ忘れておりました。
guest

回答1

0

ベストアンサー

参考になりそうなリンクです。

Photos frameworkでExifつき写真を保存する / Qiita
swiftでAVCaptureVideoDataOutputを使って位置情報付きの写真を撮影、保存したい / teratail

なんか面倒臭そうですね。

投稿2017/11/09 02:32

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maru.wk

2017/11/09 02:56

ありがとうございます。リンクを読みながら、試してみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問