【Swift UIKit】画像をカメラロールから選択/保存/取得/削除する方法!
この記事からわかること
- SwiftのUIKitで画像をカメラロールからアップロードする方法
- NSPhotoLibraryUsageDescriptionキーの指定
- 画像を選択/保存/取得/削除するメソッドの実装方法
- UIImagePickerControllerDelegateとは?
- UIImagePickerControllerとは?
- 画像ファイルの操作方法
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
SwiftのUIKitでカメラロールにある画像をアップロードしてDocumentsフォルダの中に保存する方法をまとめていきます。
画像をカメラロールからDocumentsフォルダに保存する方法
実装の流れ
- 「info.plist」にNSPhotoLibraryUsageDescriptionキーを追加
- Storyboardにビューを追加
- UIImageViewなどのUI部品をVCに用意
- 対象VCに必要なプロトコルを準拠
- 選択メソッド
- 保存メソッド
- 取得メソッド
- 削除メソッド
ポイント
- UIImagePickerControllerDelegate
- UIImagePickerController
- ファイル操作
おすすめ記事:【Swift UIKit】アプリ内からカメラで写真を撮影する方法!
ファイル操作に関してはFileManagerクラスを使用します。この記事では解説しませんので以下記事を参考にしてください。
おすすめ記事:【Swift】FileManagerでファイルを保存!操作方法や格納場所
画像の保存先
ユーザーから選択された画像を実際に保存するのはサンドボックスと呼ばれる外部とは隔離された仮想領域の中のDocumentsフォルダです。
├── AppData
│ ├── Documents
│ ├── Library
│ ├── Application Support
│ ├── Caches
│ ├── Preferences
│ ├── Saved Application State
│ └── SplashBoard
│ ├── SystemData
│ └── tmp
おすすめ記事:iOSのファイルシステム:サンドボックス構造
最初はまず流れに沿って実装してみます。詳細は後述していきます。
info.plistにNSPhotoLibraryUsageDescriptionキーを追加
アプリ内からデバイスのカメラロールにアクセスするためには「info.plist」にNSPhotoLibraryUsageDescriptionキーを追加する必要があります。
「info.plist」を開いたらKeyにNSPhotoLibraryUsageDescription
と入力し、Valueにはカメラロールを使用する旨を記載しておきます。
Storyboardにビューを追加
続いてStoryboardにUIImageViewやUIButtonを追加しておきます。画像を操作するための「選択」、「保存」、「取得」、「削除」の4つのボタンを用意しました。
UIImageViewなどのUI部品をVCに用意
Storyboard側の実装が完了したら、コードからビューと紐づけていきます。画像を表示させるためのアウトレット変数としてimageView
と、各ボタンのアクションメソッドを用意しておきます。中身は後述していきます。またそれに必要なDocumentsフォルダまでのパスを構築するメソッドも用意しておきます。
class ImageViewController: UIViewController {
// MARK: - Outlet
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - パスの構築
func docURL(_ fileName:String) -> URL? {
do {
// Docmentsフォルダ
let docsUrl = try FileManager.default.url(
for: .documentDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: false)
// URLを構築
let url = docsUrl.appendingPathComponent(fileName)
return url
} catch {
return nil
}
}
// MARK: - 選択
@IBAction func selectImage() {
}
// MARK: - 保存
@IBAction func saveImage() {
}
// MARK: - 取得
@IBAction func loadImage() {
}
// MARK: - 削除
@IBAction func deleteImage() {
}
}
定義が完了したら再度Storyboardから紐付けを忘れないようにしてください。
デリゲートプロトコルを準拠
対象となるViewControllerにはさらにUIImagePickerControllerDelegate
とUINavigationControllerDelegate
を準拠させておきます。
UIImagePickerControllerDelegate
にはユーザーが静止画像または動画を選択したことをデリゲートに伝えるためのimagePickerController
というデリゲートメソッドが用意されているのでこれを実装しておきます。
import UIKit
class ImageViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension ImageViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[.originalImage] as! UIImage // 選択された画像を取得
imageView.image = image // imageViewプロパティに格納
self.dismiss(animated: true) // 選択画面を閉じる
}
}
選択メソッドの定義
選択メソッドでやっていることは以下の通りです。
- photoLibraryを使用してデバイスが画像の選択が可能かどうか識別
- 画像を選択する種類を指定
- デリケートを設定
- 画像選択ビューを表示
@IBAction func selectImage() {
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
let pickerView = UIImagePickerController()
pickerView.sourceType = .photoLibrary
pickerView.delegate = self
self.present(pickerView, animated: true)
}
}
保存メソッドの定義
保存メソッドでやっていることは以下の通りです。
- jpeg形式の画像に変換:圧縮値も指定
- 画像のファイル名を生成
- Documentsフォルダへ画像を保存
公式リファレンス:jpegData(compressionQuality:)
@IBAction func saveImage() {
guard let imageData = imageView.image?.jpegData(compressionQuality: 1.0) else {
return
}
do {
let name = "Test"
try imageData.write(to: docURL("\(name).jpg")!)
print("画像を保存できました")
} catch {
print("\(error)")
}
}
取得メソッドの定義
取得メソッドでやっていることは以下の通りです。
- 取得する画像のファイル名を生成
- 取得する画像のファイルパスを生成
- 対象画像パスにデータが存在するか識別
- あればUIImageのイニシャライザでパスからインスタンス化
公式リファレンス:fileExists(atPath:isDirectory:)
@IBAction func loadImage() {
let name = "Test"
let path = docURL("\(name).jpg")!.path
if FileManager.default.fileExists(atPath: path) {
if let image = UIImage(contentsOfFile: path) {
imageView.image = image
}else {
print("読み込みに失敗しました")
}
}else {
print("画像が見つかりませんでした")
}
}
削除メソッドの定義
削除メソッドでやっていることは以下の通りです。
- 削除する画像のファイル名を生成
- 取得する画像のファイルURLを生成
- 対象の画像ファイルを削除
@IBAction func deleteImage() {
let name = "Test"
let url = docURL("\(name).jpg")!
do {
try FileManager.default.removeItem(at: url)
} catch {
print("削除失敗")
}
}
これで全ての実装が完了しました。正常に動作するか確認してみてください。ここからは登場したクラスやプロトコルなどの使い方や概要をまとめていきます。
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 // imageViewプロパティに格納
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)
カメラロールから画像を選択する方法としてPhotoKitを使用する方法もあります。詳細は以下の記事を参考にしてください。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。