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

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

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

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

Q&A

解決済

1回答

1055閲覧

UIImageViewを、カメラロールから取得した画像のアスペクト比の形にしたい

mimamo

総合スコア44

Swift

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

0グッド

0クリップ

投稿2019/01/16 03:44

編集2019/01/16 10:39

前提・実現したいこと

すでにUIImageViewを設置しています。
カメラロールから取得した画像をUIImageView(aspect fit)に表示されるようにしているのですが、空白の余白が残るのを避けたいです。
そのため、取得した画像のアスペクト比をUIImageViewにも反映させられたらなと思っています。
ですがなかなかうまくいきません。ご教授よろしくお願いいたします。

理想のイメージはこのようになります。
イメージ説明
写真とUIImageViewのアスペクト比が一致しています。

ご教授よろしくお願いいたします。

該当のソースコード

Swift

1 2 @IBOutlet weak var getphoto: UIImageView! 3 4 //カメラロールから写真を選択する処理 5 @IBAction func choosePicture() { 6 // カメラロールが利用可能か? 7 if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) { 8 // 写真を選ぶビュー 9 let pickerView = UIImagePickerController() 10 // 写真の選択元をカメラロールにする 11 // 「.camera」にすればカメラを起動できる 12 pickerView.sourceType = .photoLibrary 13 // デリゲート 14 pickerView.delegate = self 15 // ビューに表示 16 self.present(pickerView, animated: true) 17 } 18 } 19 20 21 // 写真を選んだ後に呼ばれる処理 22 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { 23 // 選択した写真を取得する 24 let image = info[UIImagePickerControllerOriginalImage] as! UIImage 25 26 27 //photoの縦横サイズを取得 28 pickerphotowidth = image.size.width 29 pickerphotoheight = image.size.height 30 31 //横幅をスクリーン画面の1/4、アスペクト比維持のRect作成 32 let photorect:CGRect = CGRect(x: 0, y: 0, width: screenWidth/4, height: (screenWidth*photoheight)/photowidth*4) 33 34 getphoto.frame = photorect; 35 getphoto.center = CGPoint(x:screenWidth/2, y:screenHeight/2) 36 37 38 39 // ビューに表示する 40 self.getphoto.image = image 41 // 写真を選ぶビューを引っ込める 42 self.dismiss(animated: true) 43 } 44

###頂いたコードを参考に記述したもの

Swift

1 extension CGRect { 2 func aspectFit(contentSize: CGSize, stretchble: Bool, integer: Bool) -> CGRect { 3 let xZoom = width / contentSize.width 4 let yZoom = height / contentSize.height 5 let zoom = stretchble ? min(xZoom, yZoom) : min(xZoom, yZoom, 1) 6 7 if integer { 8 let newWidth = max(Int(contentSize.width * zoom), 1) 9 let newHeight = max(Int(contentSize.height * zoom), 1) 10 let newX = Int(origin.x) + (Int(width) - newWidth) / 2 11 let newY = Int(origin.y) + (Int(height) - newHeight) / 2 12 return CGRect(x: newX, y: newY, width: newWidth, height: newHeight) 13 } else { 14 let newWidth = contentSize.width * zoom 15 let newHeight = contentSize.height * zoom 16 let newX = origin.x + (width - newWidth) / 2 17 let newY = origin.y + (height - newHeight) / 2 18 return CGRect(x: newX, y: newY, width: newWidth, height: newHeight) 19 } 20 } 21 } 22 23 24 25 // 写真を選んだ後に呼ばれる処理 26 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { 27 // 選択した写真を取得する 28 let image = info[UIImagePickerControllerOriginalImage] as! UIImage 29 30 //透過していた画像を取り戻す 31 getphoto.alpha = 1.0 32 33 34 35 36 37 38 getphoto.frame = CGRect(x: 0, y: 0, width: screenWidth / 4, height: screenHeight / 4).aspectFit(contentSize: image.size, stretchble: true, integer: true) 39 getphoto.center = CGPoint(x:screenWidth/2, y:screenHeight/2) 40 41 42 // ビューに表示する 43 self.getphoto.image = image 44 // 写真を選ぶビューを引っ込める 45 self.dismiss(animated: true) 46 }

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

Swiftのversionは4.1.2
Xcodeのversionは9.4.1

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

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

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

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

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

guest

回答1

0

ベストアンサー

横幅をスクリーン画面の1/4と決めてしまうと、極端な話ですが細く縦長い画像を読み込んだ場合に画面から画像がはみ出すことになりますのでおすすめしません(=高さ制限がない)。

自分の場合はある矩形にaspectFitしたときの座標を算出する関数を作って、
その矩形を使うようにしています。
これならば細長の画像でもはみ出すことはありません。

swift

1extension CGRect { 2 func aspectFit(contentSize: CGSize, stretchble: Bool, integer: Bool) -> CGRect { 3 let xZoom = width / contentSize.width 4 let yZoom = height / contentSize.height 5 let zoom = stretchble ? min(xZoom, yZoom) : min(xZoom, yZoom, 1) 6 7 if integer { 8 let newWidth = max(Int(contentSize.width * zoom), 1) 9 let newHeight = max(Int(contentSize.height * zoom), 1) 10 let newX = Int(origin.x) + (Int(width) - newWidth) / 2 11 let newY = Int(origin.y) + (Int(height) - newHeight) / 2 12 return CGRect(x: newX, y: newY, width: newWidth, height: newHeight) 13 } else { 14 let newWidth = contentSize.width * zoom 15 let newHeight = contentSize.height * zoom 16 let newX = origin.x + (width - newWidth) / 2 17 let newY = origin.y + (height - newHeight) / 2 18 return CGRect(x: newX, y: newY, width: newWidth, height: newHeight) 19 } 20 } 21}

使い方の例:

swift

1getphoto.frame = CGRect(x: 0, y: 0, width: screenWidth / 4, height: screenHeight / 4).aspectFit(contentSize: image.size, stretchble: true, integer: true)

※多少の誤差はでます。

投稿2019/01/16 04:24

takabosoft

総合スコア8356

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

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

mimamo

2019/01/16 04:58

ありがとうございます! 無知ですみません、お伺いしたいことがあります。 extension CGRect{ ... } のwidthやorigin.xなどについてですが、これは事前にどこかで宣言しておく必要があるということでしょうか。 また、この場合にwidthはgetphotoの横幅のことでしょうか。
takabosoft

2019/01/16 05:44 編集

上記のソースコードを新規ファイルでもいいですし、どこでもいいのでまるごと貼り付けてください。 extension CGRect {} とあるように、CGRectのメンバ関数を拡張(=追加)した感じです。 中で使われているwidth(=self.width)はCGRect自身のwidthを指します。 これらはすでにCGRectが持っている変数ですので、「どこかで宣言しておく」必要はありません。
mimamo

2019/01/16 10:40

ありがとうございます。 貼り付けると extension CGRect {} の範囲で 1、Declaration is only valid at file scope 2、Use of unresolved identifier 'width' 3、Use of unresolved identifier 'height' 4、Did you mean 'right'? などといろいろ忠告が出てしまいます。
takabosoft

2019/01/17 00:29

extension CGRect {} はクラスの外(グローバル)に置いてますか?すみません、どこでもいいというのは語弊がありました。
mimamo

2019/01/17 14:41

なるほど、無事できました!! ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問