Swift - 画像ファイルを Photo Library に保存・取得する方法
ここでは、Swift で画像ファイルを写真ライブラリ (Photo Library) に保存・取得する方法をご説明します。
前回 「カメラで写真を撮る方法」で、Take Photo というボタンをタップした時に、カメラが起動して写真を撮り、元の画面に撮った写真が表示されるアプリを作りました。
今回はそのアプリに Save to Photo Library、Clear Photo、Select from Photo Library の三つのボタンを追加して、画像ファイルを Photo Library に保存・取得する機能を追加します。
写真を撮る iOS アプリにボタンとアクションを追加する
まずは、カメラで写真を撮る iOS アプリに、今回テストに使う三つのボタンを追加して、アクションを作っておきます。
カメラで写真を撮る iOS アプリをまだ作っていない方は「カメラで写真を撮る方法」を参考に作っておいてください。
プロジェクトを開き、Main ストーリーボードの View Controller の Take Photo ボタンの下に、Save to Photo Library、Clear Photo、Select from Photo Library の三つのボタンを追加します。
ここでは Stack View に入れていますが、配置や色など、適当で大丈夫です。
Save to Photo Library、Clear Photo、Select from Photo Library ボタンから、それぞれ、saveToPhotoLibraryTapped、clearPhotoTapped、selectFromPhotoLibraryTapped という名前で TouchUpInside のアクションを作っておきます。
@IBAction func saveToPhotoLibraryTapped(_ sender: Any) {
}
@IBAction func clearPhotoTapped(_ sender: Any) {
}
@IBAction func selectFromPhotoLibraryTapped(_ sender: Any) {
}
Clear Photo ボタンをタップした時には、UIImageView の画像を削除したいので、次の一行のコードを追加しておきます。
imageView は UIImageView のアウトレットです。
@IBAction func clearPhotoTapped(_ sender: Any) {
imageView.image = nil
}
Swift で画像ファイルを Photo Library に保存する方法
Swift で Photo Library に UIImageView に表示されている写真を保存します。
まず、iOS アプリ内で Photo Library に画像を保存・取得するのに、info.plist に Privacy - Photo Library Usage Description (NSPhotoLibraryUsageDescription) と Privacy - Photo Library Additions Usage Description (NSPhotoLibraryAddUsageDescription) を追加しておきます。
Privacy - Photo Library Usage Description (NSPhotoLibraryUsageDescription) だけでも、Photo Library に写真を保存できることはできるのですが、エラーが出ることがあるので、Photo Library への書き込み専用の Privacy - Photo Library Additions Usage Description (NSPhotoLibraryAddUsageDescription) も追加しています。
続いて、Save to Photo Library ボタンをタップした時に、UIImageView の image を Photo Library に保存するコードを書きます。
ViewController.swift に先ほど作った saveToPhotoLibraryTapped() を以下のように変更し、image() も追加します。
@IBAction func saveToPhotoLibraryTapped(_ sender: Any) {
guard let image = imageView.image else { return }
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image(image:didFinishSavingWithError:contextInfo:)), nil)
}
@objc func image(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeRawPointer) {
if let error = error {
print("Failed to save photo: \(error)")
} else {
print("Photo saved successfully.")
}
}
2 行目では、guard let で imageView(UIImageView のアウトレット)から image データを取得し、もし取得できなかったら return しています。
3 行目で UIImageWriteToSavedPhotosAlbum() メソッドを使って、画像データを Photo Library のカメラロールのアルバムに保存しています。
UIImageWriteToSavedPhotosAlbum の構文は以下の通りで、第二引数と第三引数で、保存処理後にこの View Controller の image() が呼ばれるように指定しています。
@func UIImageWriteToSavedPhotosAlbum(_ image: UIImage,
_ completionTarget: Any?,
_ completionSelector: Selector?,
_ contextInfo: UnsafeMutableRawPointer?)}
6 行目から 11 行目の image() 内では、error が入っている時は、エラーメッセージを、成功した時は "Photo saved successfully." をプリントするようにしています。
画像ファイルを Photo Library に保存するコードは以上です。
Swift で画像を Photo Library から選択して表示する方法
次は、Swift で写真ライブラリ (Photo Library) に保存されている画像を取得します。
Select from Photo Library ボタンをタップした時に、Photo Library から写真を選択する Image Picker 画面をたちあげ、選択された 画像を UIImageView に表示するコードを書きます。
UIImagePickerController はカメラで写真を撮る時にも使いましたが、それとほぼ同じ方法で sourceType を .camera から .photoLibrary に変更するだけで、Photo Library から写真を選択することができます。
カメラとフォトライブラリで同じ UIImagePickerController を使うようにコードを変更します。
こちらが変更後の ViewController.swift で、ハイライトされている箇所が変更した箇所です。
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
@IBOutlet weak var imageView: UIImageView!
var imagePicker: UIImagePickerController!
override func viewDidLoad() {
super.viewDidLoad()
imagePicker = UIImagePickerController()
imagePicker.delegate = self
}
@IBAction func takePhotoTapped(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.sourceType = .camera
self.present(imagePicker, animated: true, completion: nil)
}
else {
print("Camera not available.")
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true)
guard let image = info[.originalImage] as? UIImage else {
print("Image not found.")
return
}
imageView.image = image
}
@IBAction func saveToPhotoLibraryTapped(_ sender: Any) {
guard let image = imageView.image else { return }
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image(image:didFinishSavingWithError:contextInfo:)), nil)
}
@objc func image(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeRawPointer) {
if let error = error {
print("Failed to save photo: \(error)")
} else {
print("Photo saved successfully.")
}
}
@IBAction func clearPhotoTapped(_ sender: Any) {
imageView.image = nil
}
@IBAction func selectFromPhotoLibraryTapped(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
imagePicker.sourceType = .photoLibrary
self.present(imagePicker, animated: true, completion: nil)
}
else {
print("Photo Library not available.")
}
}
}
54 ~ 60 行目が、Select from Photo Library ボタンがタップされた時に実行されるコードです。
54 行目で Photo Library が利用可能かチェックしています。
55 行目で UIImagePickerController の sourceType を .photoLibrary に設定しています。
56 行目の self.present() メソッドで、UIImagePickerController を表示し、Photo Library から写真を選択する画面を起動します。
ユーザーがフォトライブラリの写真をタップした時に、25 ~ 34 行目の imagePickerController(_:didFinishPickingMediaWithInfo:) メソッドが実行され、その中で選択された写真を Image Viwer に表示しています。
これで、Swift で画像を Photo Library から選択して表示するコードが書けました。
iOS アプリを iPhone にインストールしてテストする
写真を撮る箇所がシミュレーターでできないので、iPhone にインストールしてテストします。
作った iOS アプリを iPhone にインストールする方法がわからない方は「Xcode からアプリを iPhone にインストールして実行する方法」をご覧ください。
iPhone を指定してこのアプリを実行すると、以下のような画面が表示されるので、Take Photo ボタンをタップします。
カメラの利用許可を求めるダイアログが表示されるので、OK をタップします。
カメラが起動するので、写真を撮ります。
この写真でよければ、Use Photo をタップします。撮り直したい時は Retake をタップして撮り直してください。
Use Photo をタップすると、カメラが閉じ、元の画面に戻って、撮った写真が画面に表示されるので、Save to Photo Library をタップして写真を保存します。
アプリをインストールしてはじめて、Photo Library にアクセスしようとした時に、利用許可を求めるダイアログが表示されるので、OK をタップします。
Xcode の output window に Photo saved successfully. と表示され、写真アプリを開くとこの画像が入っています。
Clear Photo ボタンをタップして、Image View の画像を一旦削除します。
Select from Photo Library ボタンをタップすると、Photo Library の写真が表示されます。
Photo Library の写真をタップすると、画面が閉じ、元の画面の UIImageView に選択した画像が表示されます。
ちなみに、何度も Save to Photo Library ボタンをタップすると、その数だけ画像が Photo Library に保存されます。
以上、Swift で画像ファイルを写真ライブラリ (Photo Library) に保存・取得する方法をご説明しました。