【Swift UIKit】画像をカメラロールから選択/保存/取得/削除する方法!

この記事からわかること

  • SwiftUIKit画像カメラロールからアップロードする方法
  • NSPhotoLibraryUsageDescriptionキーの指定
  • 画像を選択/保存/取得/削除するメソッド実装方法
  • UIImagePickerControllerDelegateとは?
  • UIImagePickerControllerとは?
  • 画像ファイルの操作方法

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

SwiftのUIKitでカメラロールにある画像をアップロードしてDocumentsフォルダの中に保存する方法をまとめていきます。

画像をカメラロールからDocumentsフォルダに保存する方法

実装の流れ

  1. 「info.plist」にNSPhotoLibraryUsageDescriptionキーを追加
  2. Storyboardにビューを追加
  3. UIImageViewなどのUI部品をVCに用意
  4. 対象VCに必要なプロトコルを準拠
  5. 選択メソッド
  6. 保存メソッド
  7. 取得メソッド
  8. 削除メソッド

ポイント

おすすめ記事:【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キーを追加する必要があります。

【Swift UIKit】画像をカメラロールから保存/取得/削除する方法!

「info.plist」を開いたらKeyにNSPhotoLibraryUsageDescriptionと入力し、Valueにはカメラロールを使用する旨を記載しておきます。

Storyboardにビューを追加

続いてStoryboardにUIImageViewやUIButtonを追加しておきます。画像を操作するための「選択」、「保存」、「取得」、「削除」の4つのボタンを用意しました。

【Swift UIKit】画像をカメラロールから保存/取得/削除する方法!

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にはさらにUIImagePickerControllerDelegateUINavigationControllerDelegateを準拠させておきます。

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) // 選択画面を閉じる 
    }
}

選択メソッドの定義

選択メソッドでやっていることは以下の通りです。

  1. photoLibraryを使用してデバイスが画像の選択が可能かどうか識別
  2. 画像を選択する種類を指定
  3. デリケートを設定
  4. 画像選択ビューを表示
@IBAction  func selectImage() {
    if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
        let pickerView = UIImagePickerController()
        pickerView.sourceType = .photoLibrary
        pickerView.delegate = self
        self.present(pickerView, animated: true)
    }
}

保存メソッドの定義

保存メソッドでやっていることは以下の通りです。

  1. jpeg形式の画像に変換:圧縮値も指定
  2. 画像のファイル名を生成
  3. 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)")
  }
}

取得メソッドの定義

取得メソッドでやっていることは以下の通りです。

  1. 取得する画像のファイル名を生成
  2. 取得する画像のファイルパスを生成
  3. 対象画像パスにデータが存在するか識別
  4. あれば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("画像が見つかりませんでした")
  }
}

削除メソッドの定義

削除メソッドでやっていることは以下の通りです。

  1. 削除する画像のファイル名を生成
  2. 取得する画像のファイルURLを生成
  3. 対象の画像ファイルを削除
@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]
)
  1. picker:画像ピッカーインターフェイスを管理するコントローラー
  2. 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クラスです。このクラスを使用することでカメラロールから画像を選択したり、カメラを起動し撮影した画像を使用することができるようになります。そのためには以下の手順を踏む必要があります。

  1. デバイスが指定された選択方法で画像の選択が可能かどうか識別
  2. 画像を選択する種類を指定
  3. デリケートを設定
  4. 画像選択ビューを表示
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を使用する方法もあります。詳細は以下の記事を参考にしてください。

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index