【Swift/UIImagePickerController】アプリ内からカメラで写真を撮影する方法!

この記事からわかること
- SwiftのUIKitでアプリ内からカメラを起動して写真を撮影する方法
- NSCameraUsageDescriptionキーの指定
- UIImagePickerControllerDelegateとは?
- UIImagePickerControllerとは?
- 画像ファイルの操作方法
index
[open]
\ アプリをリリースしました /
SwiftのUIKitでアプリ内からカメラを起動して撮影する方法をまとめていきます。
カメラを起動して写真を撮影する方法
Swiftを使って自作したアプリ内からカメラを起動して写真を撮影する方法は2つ存在します。
方法1:UIImagePickerControllerクラス
1つ目はUIImagePickerController
クラスを使用した方法です。フレームワークなどを導入せずに実装でき、コードもシンプルなので実装の手軽さでは圧倒的に軍配が上がります。
またiOSの「カメラ」アプリのようなUIをそのまま使用できるのもメリットの1つです。

方法2:AVFoundation
2つ目はAVFoundation
を使用した方法です。実装するのはなかなか手間がかかりますがカスタマイズ性が高く柔軟なカメラアプリを開発することができます。
撮影ボタンの位置やカメラビューのサイズなどを好きなように配置できるので独自のカメラアプリを作成するのにおすすめです。

おすすめ記事:【Swift/AVFoundation】アプリ内からカメラを起動し写真撮影をする方法
UIImagePickerControllerクラスの実装方法
今回はUIImagePickerControllerクラスを使用した方法で実装してみます。
実装の流れ
- 「info.plist」にNSCameraUsageDescriptionキーを追加
- Storyboardにビューを追加
- UIImageViewなどのUI部品をVCに用意
- カメラを起動する処理を定義
- 対象VCに必要なプロトコルを準拠
ポイント
- UIImagePickerControllerDelegate
- UIImagePickerController
おすすめ記事:【Swift UIKit】画像をカメラロールから選択/保存/取得/削除する方法!
info.plistにNSCameraUsageDescriptionキーを追加
アプリ内からデバイスのカメラにアクセスするためには「info.plist」にNSCameraUsageDescriptionキーを追加する必要があります。

「info.plist」を開いたらKeyにNSCameraUsageDescription
と入力し、Valueにはカメラ使用する旨を記載しておきます。自動でPrivacy - Camera Usage Description
に変換されます。
Storyboardにビューを追加
続いてStoryboardにUIImageViewやUIButtonを追加しておきます。今回はカメラを起動するためのボタンと撮影した写真を表示させる場所を用意しました。

UIImageViewなどのUI部品をVCに用意
Storyboard側の実装が完了したら、コードからビューと紐づけていきます。画像を表示させるためのアウトレット変数としてimageView
と、撮影ボタンのアクションメソッドを用意しておきます。中身は後述していきます。
import UIKit
class ViewController: UIViewController {
// MARK: - ImageView
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - 撮影ボタンアクション
@IBAction func takePictureTapped() {
}
}
定義が完了したら再度Storyboardから紐付けを忘れないようにしてください。
カメラを起動する処理を定義
続いてボタンのアクションにカメラを起動させる準備をしていきます。UIImagePickerController
クラスのisSourceTypeAvailable
メソッドでcamera
が使用できるかを識別し、問題なければカメラビューを表示させています。
- cameraを使用してデバイスが画像の選択が可能かどうか識別
- 画像を選択する種類を指定
- デリケートを設定
- カメラビューを表示
// MARK: - 撮影ボタンアクション
@IBAction func takePictureTapped() {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
let pickerView = UIImagePickerController()
pickerView.sourceType = .camera
pickerView.delegate = self
self.present(pickerView, animated: true)
}
}
デリゲートプロトコルを準拠
対象となるViewControllerにはさらにUIImagePickerControllerDelegate
とUINavigationControllerDelegate
を拡張して準拠させておきます。
UIImagePickerControllerDelegate
にはユーザーが静止画像または動画を選択したことをデリゲートに伝えるためのimagePickerController
というデリゲートメソッドが用意されているのでこれを実装しておきます。ここではカメラで撮影した画像を取得してimageView
に格納しています。
おすすめ記事:【Swift】delegate(デリゲート)とは?使い方とメリット
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[.originalImage] as! UIImage // カメラで撮影した画像を取得
imageView.image = image
self.dismiss(animated: true)
}
}
これで全ての実装が完了しました。正常に動作するか実機にビルドして確認してみてください。

カメラで撮影した画像をそのままカメラロールに保存したい場合か以下の記事を参考にしてください。
おすすめ記事:【Swift UIKit】画像をカメラロールに保存する方法!UIImageWriteToSavedPhotosAlbum
全体のコード
import UIKit
class ViewController: UIViewController {
// MARK: - ImageView
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - 撮影ボタンアクション
@IBAction func takePictureTapped() {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
let pickerView = UIImagePickerController()
pickerView.sourceType = .camera
pickerView.delegate = self
self.present(pickerView, animated: true)
}
}
}
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[.originalImage] as! UIImage
imageView.image = image
self.dismiss(animated: true) // 選択画面を終了する
}
}
ここからは登場したクラスやプロトコルなどの使い方や概要をまとめていきます。
UIImagePickerControllerDelegateとは?
公式リファレンス:UIImagePickerControllerDelegate
@MainActor protocol UIImagePickerControllerDelegate
UIImagePickerControllerDelegate
は画像を選択するビューとやり取りを実装するためのメソッドが定義されているプロトコルです。
imagePickerControllerメソッド
デリゲートメソッドのimagePickerController
はユーザーが静止画像または動画を選択したことをデリゲートに伝えるメソッドです。
optional func imagePickerController(
_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]
)
- picker:画像ピッカーインターフェイスを管理するコントローラー
- info:元の画像と編集された画像を含む辞書型
引数info
から選択された画像にアクセスできます。ディクショナリ(辞書)型のデータ構造になっており、キー値はUIImagePickerController.InfoKey
として定義されています。今回はその中の元のデータを取得したいので.originalImage
を指定しています。
公式リファレンス:UIImagePickerController.InfoKey
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[.originalImage] as! UIImage
imageView.image = image
self.dismiss(animated: true)
}
UIImagePickerControllerクラスとは?
@MainActor class UIImagePickerController : UINavigationController
公式リファレンス:UIImagePickerControllerクラス
UIImagePickerControllerは画像や動画などのメディア類を選択するシステムインターフェースを管理するViewControllerクラスです。このクラスを使用することでカメラロールから画像を選択したり、カメラを起動し撮影した画像を使用することができるようになります。そのためには以下の手順を踏む必要があります。
- デバイスが指定された選択方法で画像の選択が可能かどうか識別
- 画像を選択する種類を指定
- デリケートを設定
- 画像選択ビューを表示
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
let pickerView = UIImagePickerController()
pickerView.sourceType = .photoLibrary
pickerView.delegate = self
self.present(pickerView, animated: true)
}
isSourceTypeAvailableメソッド
公式リファレンス:isSourceTypeAvailableメソッド
class func isSourceTypeAvailable(_ sourceType: UIImagePickerController.SourceType) -> Bool
isSourceTypeAvailableは指定された方法(sourceType)でデバイスがメディアの選択をサポートしているかどうかを問い合わせるメソッドです。方法はUIImagePickerController.SourceType
に定義された値で指定でき、カメラを起動して画像を撮影することができるようにするにはここで.camera
をサポートしているかチェックし後で明示的に.camera
を指定する必要があります。
選択するビューの構築
指定方法をサポートしていればUIImagePickerController
クラスを使って選択するビューを構築していきます。ここではインスタンス化と選択方法の指定、デリゲートの設定、ビューの表示をおこなっています。
let pickerView = UIImagePickerController()
pickerView.sourceType = .photoLibrary
pickerView.delegate = self
self.present(pickerView, animated: true)
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。