This document provides code samples for working with photos and the camera in iOS. It includes code to:
1. Request camera and photo library permissions.
2. Open the camera or photo library using UIImagePickerController.
3. Display selected photos and handle the delegate callbacks.
4. Save photos to the camera roll or a custom album using Photos framework APIs.
5. Retrieve metadata from photos using Photos framework objects like PHAsset.
It also discusses using CoreImage for features like adding stickers to photos and face detection.
7. info.plist
設定Usage Description
取用相機說明:
Privacy - Camera Usage Description
取用照片說明:
Privacy - Photo Usage Description
ata without a usage description. The app's Info.plist must contain an NSCameraUsageDescription
Error
10. Important
The Assets Library framework is deprecated as of iOS
9.0. Instead, use the Photos framework instead, which in
iOS 8.0 and later provides more features and better
performance for working with a user’s photo library.
PhotosAssetsLibrary
iOS 8.0+
21. 實作 - 5.取得照片內容metadata
//取得PHAsset, iOS 4.1-11.0, Deprecated
if let assetURL = info[UIImagePickerControllerReferenceURL] as? NSURL {
let asset = PHAsset.fetchAssets(withALAssetURLs: [assetURL as URL], options: nil)
guard let result = asset.firstObject else {
return
}
//取得ImageData
PHImageManager.default().requestImageData(for: result , options: nil, resultHandler:{
(data, responseString, imageOriet, info) -> Void in
let imageData: NSData = data! as NSData
if let imageSource = CGImageSourceCreateWithData(imageData, nil) {
let imgprop = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil)! as NSDictionary
print(“....metadata....(imgprop)")
let pixelHeight = imgprop["PixelHeight"] as? Int
let pixelWidth = imgprop["PixelWidth"] as? Int
print("Height:(pixelHeight ?? 0)")
print("Width:(pixelWidth ?? 0)")
}
})
}
//取得PHAsset, iOS 11.0+
if let result = info[UIImagePickerControllerPHAsset] as? PHAsset {
22. 實作 - 6.將照片儲存至
自訂相簿-1
var myAlbum: PHAssetCollection?
override func viewDidLoad() {
super.viewDidLoad()
//取得自訂相簿,不存在則建立自定相簿
if let collection = fetchAssetCollection(with: "SwiftGirls") {
myAlbum = collection
} else {
PHPhotoLibrary.shared().performChanges({
PHAssetCollectionChangeRequest
.creationRequestForAssetCollection(withTitle: "SwiftGirls")
}) { success, error in
if success {
print("Custom album create success.")
if let album = self
.fetchAssetCollection(with: "SwiftGirls") {
self.myAlbum = album
}
} else {
print("error creating album: (String(describing: error))")
}
}
}
}
//請求照片權限
PHPhotoLibrary.requestAuthorization { (status) in
switch status {
case .authorized:
print("authorized..")
case .denied:
print("denied..")
case .notDetermined:
print("notDetermined..")
case .restricted:
print("restricted..")
}
}
//取得PHAsset, iOS 11.0+
// if let result = info[UIImagePickerControllerPHAsset] as? PHAsset {
//取得PHAsset, iOS 4.1-11.0, Deprecated
if let assetURL = info[UIImagePickerControllerReferenceURL] as? NSURL {
let asset = PHAsset.fetchAssets(withALAssetURLs: [assetURL as URL], options: nil)
guard let result = asset.firstObject else {
return
}
//取得ImageData
PHImageManager.default().requestImageData(for: result , options: nil, resultHandler:{
(data, responseString, imageOriet, info) -> Void in
let imageData: NSData = data! as NSData
if let imageSource = CGImageSourceCreateWithData(imageData, nil) {
let imgprop = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil)! as NSDictionary
print("....metadata....\n\(imgprop)")
let pixelHeight = imgprop["PixelHeight"] as? Int
let pixelWidth = imgprop["PixelWidth"] as? Int
print("Height:\(pixelHeight ?? 0)")
print("Width:\(pixelWidth ?? 0)")
}
})
}
var myAlbum: PHAssetCollection?
//取得自訂相簿,不存在則建立自定相簿
if let collection = self.fetchAssetCollection(with: "SwiftGirls") {
self.myAlbum = collection
} else {
PHPhotoLibrary.shared().performChanges({
PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: "SwiftGirls")
}) { success, error in
if success {
print("Custom album create success.")
if let album = self.fetchAssetCollection(with: "SwiftGirls") {
self.myAlbum = album
}
} else {
print("error creating album: \(String(describing: error))")
}
}
}
//依照相簿名稱取得相簿,不存在則回nil
func fetchAssetCollection(with name: String) -> PHAssetCollection? {
let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "title = %@", name)
let collections = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions)
if let collection = collections.firstObject {
return collection
}
return nil
}
if self.img.image == nil {
return
}
guard myAlbum != nil else {
print("Custom album not found.")
return
}
//儲存照片至指定相簿
PHPhotoLibrary.shared().performChanges({
let assetChangeRequest = PHAssetChangeRequest.creationRequestForAsset(from: self.img.image!)
let assetPlaceHolder = assetChangeRequest.placeholderForCreatedAsset
let albumChangeRequest = PHAssetCollectionChangeRequest(for: self.myAlbum!)
let enumeration: NSArray = [assetPlaceHolder!]
albumChangeRequest!.addAssets(enumeration)
}, completionHandler: {success, error in
if success {
print("save success.")
} else {
print("error creating asset: \(String(describing: error))")
}
})