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

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

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

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

解決済

2回答

812閲覧

[swift]キャプチャした画像のimageViewへの表示

programan

総合スコア25

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

0クリップ

投稿2018/06/22 10:35

キャプチャした画像をimageViewに常に横いっぱいに広げたい

swiftの勉強として簡単なカメラアプリの制作をしています。
キャプチャした画像をデバイスが横向きの時と縦向きの時で同じようにimageViewにいっぱいに表示させたいです。
以下に例を示します。
●デバイスが縦向きで撮影した時のimageViewは
イメージ説明
●デバイスが横向きで撮影した時のimageViewは
イメージ説明

このように実現させたいです

該当のソースコード

ViewController.swift

1import UIKit 2import AVFoundation 3import Photos 4 5extension UIViewController:AVCapturePhotoCaptureDelegate { 6 //映像をキャプチャする 7 public func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { 8 //データを取り出す 9 guard let photoData = photo.fileDataRepresentation() else { 10 return 11 } 12 //Dataから写真イメージを作る 13 if let stillImage = UIImage(data: photoData) { 14 //移動先のビューコントローラーを参照する 15 let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "preview")as! previewViewController 16 nextVC.image = stillImage 17 //シーンを移動する 18 present(nextVC, animated: true, completion: nil) 19 } 20 } 21} 22 23class ViewController: UIViewController { 24 25 @IBOutlet weak var previewView: UIView! 26 @IBOutlet weak var shutterButton: UIButton! 27 var previewLayer: AVCaptureVideoPreviewLayer! 28 // インスタンスの作成 29 var session = AVCaptureSession() 30 var photoOutputObj = AVCapturePhotoOutput() 31 // 通知センターを作る 32 let notification = NotificationCenter.default 33 // プライバシーと入出力のステータス 34 var authStatus:AuthorizedStatus = .authorized 35 var inOutStatus:InputOutputStatus = .ready 36 // 認証のステータス 37 enum AuthorizedStatus { 38 case authorized 39 case notAuthorized 40 case failed 41 } 42 // 入出力のステータス 43 enum InputOutputStatus { 44 case ready 45 case notReady 46 case failed 47 } 48 49 // ビューが表示された直後に実行 50 override func viewDidAppear(_ animated: Bool) { 51 super.viewDidAppear(animated) 52 // セッション実行中ならば中断する 53 guard !session.isRunning else { 54 return 55 } 56 // カメラのプライバシー認証確認 57 cameraAuth() 58 // 入出力の設定 59 setupInputOutput() 60 // カメラの準備ができているかどうか 61 if (authStatus == .authorized)&&(inOutStatus == .ready){ 62 // プレビューレイヤの設定 63 setPreviewLayer() 64 // セッション開始 65 session.startRunning() 66 shutterButton.isEnabled = true 67 } else { 68 // アラートを出す 69 showAlert(appName: "カメラ") 70 } 71 } 72 73 // シャッターボタンで実行する 74 @IBAction func takePhoto(_ sender: Any) { 75 if (authStatus == .authorized)&&(inOutStatus == .ready){ 76 let captureSetting = AVCapturePhotoSettings() 77 captureSetting.flashMode = .auto 78 captureSetting.isAutoStillImageStabilizationEnabled = true 79 captureSetting.isHighResolutionPhotoEnabled = false 80 // キャプチャのイメージ処理はデリゲートに任せる 81 photoOutputObj.capturePhoto(with: captureSetting, delegate: self) 82 } else { 83 // カメラの利用を許可しなかったにも関わらずボタンをタップした(初回起動時のみ) 84 showAlert(appName: "カメラ") 85 } 86 } 87 88 // カメラのプライバシー認証確認 89 func cameraAuth(){ 90 let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video) 91 switch status { 92 case .notDetermined: 93 // 初回起動時 94 AVCaptureDevice.requestAccess(for: AVMediaType.video, 95 completionHandler: { [unowned self] authorized in 96 print("初回", authorized.description) 97 if authorized { 98 self.authStatus = .authorized 99 } else { 100 self.authStatus = .notAuthorized 101 }}) 102 case .restricted, .denied: 103 authStatus = .notAuthorized 104 case .authorized: 105 authStatus = .authorized 106 } 107 } 108 109 // 入出力の設定 110 func setupInputOutput(){ 111 //解像度の指定 112 session.sessionPreset = AVCaptureSession.Preset.photo 113 // 入力の設定 114 do { 115 //デバイスの取得 116 let device = AVCaptureDevice.default( 117 AVCaptureDevice.DeviceType.builtInWideAngleCamera, 118 for: AVMediaType.video, // ビデオ入力 119 position: AVCaptureDevice.Position.back) // バックカメラ 120 121 // 入力元 122 let input = try AVCaptureDeviceInput(device: device!) 123 if session.canAddInput(input){ 124 session.addInput(input) 125 } else { 126 print("セッションに入力を追加できなかった") 127 return 128 } 129 } catch let error as NSError { 130 print("カメラがない (error)") 131 return 132 } 133 134 // 出力の設定 135 if session.canAddOutput(photoOutputObj) { 136 session.addOutput(photoOutputObj) 137 } else { 138 print("セッションに出力を追加できなかった") 139 return 140 } 141 } 142 func convertUIOrientation2VideoOrientation(f: () -> UIInterfaceOrientation) -> AVCaptureVideoOrientation? { 143 let v = f() 144 switch v { 145 case UIInterfaceOrientation.unknown: return nil 146 default: 147 return ([ 148 .portrait: .portrait, 149 .portraitUpsideDown: .portraitUpsideDown, 150 .landscapeLeft: .landscapeLeft, 151 .landscapeRight: .landscapeRight 152 ])[v] 153 } 154 } 155 156 func appOrientation() -> UIInterfaceOrientation { 157 return UIApplication.shared.statusBarOrientation 158 } 159 160 // プレビューレイヤの設定 161 func setPreviewLayer(){ 162 // プレビューレイヤを作る 163 previewLayer = AVCaptureVideoPreviewLayer(session: session) 164 previewLayer.frame = view.bounds 165 previewLayer.masksToBounds = true 166 previewLayer.videoGravity = AVLayerVideoGravity.resizeAspect 167 if let orientation = self.convertUIOrientation2VideoOrientation(f: { return self.appOrientation() } ) { 168 previewLayer.connection?.videoOrientation = orientation 169 } 170 // previewViewに追加する 171 previewView.layer.addSublayer(previewLayer) 172 } 173 174 override func viewDidLayoutSubviews() { 175 super.viewDidLayoutSubviews() 176 177 if let previewLayer = previewLayer { 178 previewLayer.frame = view.bounds 179 } 180 } 181 182 // 画面の回転にも対応したい時は viewWillTransitionToSize で同じく向きを教える。 183 override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 184 super.viewWillTransition(to: size, with: coordinator) 185 186 coordinator.animate( 187 alongsideTransition: nil, 188 completion: {(UIViewControllerTransitionCoordinatorContext) in 189 //画面の回転後に向きを教える。 190 if let orientation = self.convertUIOrientation2VideoOrientation(f: {return self.appOrientation()}) { 191 self.previewLayer.connection?.videoOrientation = orientation 192 } 193 } 194 ) 195 } 196 197 198 // プライバシー認証のアラートを表示する 199 func showAlert(appName:String){ 200 let aTitle = appName + "のプライバシー認証" 201 let aMessage = "設定>プライバシー>" + appName + "で利用を許可してください。" 202 let alert = UIAlertController(title: aTitle, message: aMessage, preferredStyle: .alert) 203 // OKボタン(何も実行しない) 204 alert.addAction( 205 UIAlertAction(title: "OK",style: .default,handler: nil) 206 ) 207 // 設定を開くボタン 208 alert.addAction( 209 UIAlertAction( 210 title: "設定を開く",style: .default, 211 handler: { action in 212 UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!, options: [:], completionHandler: nil) 213 }) 214 ) 215 // アラートを表示する 216 self.present(alert, animated: false, completion:nil) 217 } 218 219 override func didReceiveMemoryWarning() { 220 super.didReceiveMemoryWarning() 221 // Dispose of any resources that can be recreated. 222 } 223 224}

previewViewController.swift

1import UIKit 2 3class previewViewController: UIViewController { 4 5 var image:UIImage? 6 @IBOutlet weak var previewView: UIImageView! 7 override func viewDidLoad() { 8 super.viewDidLoad() 9 previewView.image = image 10 // Do any additional setup after loading the view. 11 } 12 13 override func didReceiveMemoryWarning() { 14 super.didReceiveMemoryWarning() 15 // Dispose of any resources that can be recreated. 16 } 17 18 /* 19 // MARK: - Navigation 20 21 // In a storyboard-based application, you will often want to do a little preparation before navigation 22 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 23 // Get the new view controller using segue.destinationViewController. 24 // Pass the selected object to the new view controller. 25 } 26 */ 27 28}

補足情報(FW/ツールのバージョンなど)

storyboardのimageViewにaspect fit適用
xcode9.4

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

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

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

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

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

guest

回答2

0

imageViewのContent ModeはAspect Fitにしておいてください。
あとはimageViewに流し込む画像(UIImage)をそのまま表示するか、90度回転させるかのどちらかなんだと思います。

画像のサイズはUIImage.sizeプロパティ、向きはUIImage.imageOrientationで取れます。
向きだけを変えるのは

UIImage(cgImage: img.cgImage!, scale: img.scale, orientation: .left)

などと書けば実現できます。

たとえば画像が縦長だったら向きを変えるようなコードなら以下のように書けます。

var img: UIImage = ???
if img.size.width < img.size.height {
img = UIImage(cgImage: img.cgImage!, scale: img.scale, orientation: .left)
}

実際にこれでうまく行くか判らないので、
キャプチャした画像のsizeやorientationを出力してみて、どんな条件の時にどのorientationにするかを検討してもらえれば行けるとおもいます。

投稿2018/06/26 02:13

takabosoft

総合スコア8356

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

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

0

自己解決

行列を生成してUIImageの角度を強引に回転させました

投稿2018/07/02 18:32

programan

総合スコア25

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問