SlideShare a Scribd company logo
1 of 29
Download to read offline
Camera·Photo
卡麥拉·佛托的廣角鏡頭
Swift Girls Part 7
20170807
張筱姍
張筱姍
HsiaoShan Chang
目前最愛寫程式跟織毛線。
目標是開發出手作相關工具或平台讓大家可以快樂
的做手作!
KCCounter-棒針鉤針必備編織計數器
創業歐北共 紛絲專頁
Instagram
Line
影像編輯
最基本3件事情
拍照
從手機取出照片
儲存照片至手機
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
UIImagePickerController
sourceType:
UIImagePickerControllerSourceType camera -
相機
photoLibrary - 所有相簿 (預設值)
savedPhotoAlbum - 所有照片
delegate: UIImagePickerControllerDelegate &
UINavigationControllerDelegate
UIImagePickerControllerDelega
te
func imagePickerController(_ picker:
UIImagePickerController,
didFinishPickingMediaWithInfo info: [String :
Any])
func imagePickerControllerDidCancel(_ picker:
UIImagePickerController)
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+
Photos Framework iOS 8.0+
Photos Framework
Model Object
PHAssetCollection
PHAsset
PHCollectionList
Photos Framework iOS 8.0+
實作
1. 打開相機拍照
2. 打開相簿
3. 將照片顯示在畫面上
4. 儲存至相機膠卷
5. 取得照片內容metadata
6. 將照片儲存至自訂相簿
實作 - 1.打開相機拍照-1
override func viewDidLoad() {
super.viewDidLoad()
//請求相機權限
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo)
{ granted in
print("camera access:(granted)")
}
}
實作 - 1.打開相機拍照-2
@IBAction func goCamera(_ sender: Any) {
guard AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo) ==
.authorized else {
print("not authorized....")
return
}
guard UIImagePickerController.isSourceTypeAvailable(.camera) else {
print("Camera not available.”)
return
}
let controller = UIImagePickerController()
controller.sourceType = .camera
controller.delegate = self
self.present(controller, animated: true, completion: nil)
}
實作 - 2.打開相簿-1
override func viewDidLoad() {
super.viewDidLoad()
//請求照片權限
PHPhotoLibrary.requestAuthorization { (status) in
switch status {
case .authorized:
print("authorized..")
case .denied:
print("denied..")
case .notDetermined:
print("notDetermined..")
case .restricted:
print("restricted..")
}
}
}
實作 - 2.打開相簿-2
@IBAction func goPhoto(_ sender: Any) {
guard PHPhotoLibrary.authorizationStatus() == .authorized else {
print("PHPhotoLibrary not available.")
return
}
guard UIImagePickerController.isSourceTypeAvailable(.camera) else {
print("Camera not available.")
return
}
let controller = UIImagePickerController()
controller.sourceType = .photoLibrary
controller.delegate = self
self.present(controller, animated: true, completion: nil)
}
實作 - 3.將照片顯示在畫面
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any]) {
print(".....info.....n(info)")
//從info取出拍好的照片
if let pickedPhoto =
info[UIImagePickerControllerOriginalImage] as? UIImage
{
img.image = pickedPhoto
}
//把相機畫面關掉
picker.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print("Cancel imagePickerController.”)
picker.dismiss(animated: true, completion: nil)
}
實作 - 4.儲存至相機膠卷
//1. UIKit method, iOS 2.0+
UIImageWriteToSavedPhotosAlbum(pickedPhoto, nil, nil, nil)
//2. Use Photos Library ,iOS 8.0+
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAsset(from: pickedPhoto)
}, completionHandler: {success, error in
if success {
print("save success.")
} else {
print("error creating asset: (String(describing: error))")
}
})
實作 - 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 {
實作 - 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))")
}
}
}
}
實作 - 6.將照片儲存至
自訂相簿-2
//依照相簿名稱取得相簿,不存在則回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
}
實作 - 6.將照片儲存至
自訂相簿-3
//儲存照片至自訂相簿
@IBAction func saveToCustomAlbum(_ sender: Any) {
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))")
}
})
}
進階實作
加貼圖
myImageView
放原來照片
(UIImageView)
myImageView.subviews
進階實作
CoreImage
臉部辨識
Content Mode:
Aspect Fit
Homework
完成
6個實作+2個進階實作

More Related Content

Similar to SwiftGirl20170807 - Camera. Photo

Asynchronous Programming with JavaScript
Asynchronous Programming with JavaScriptAsynchronous Programming with JavaScript
Asynchronous Programming with JavaScript
WebF
 
Android programming -_pushing_the_limits
Android programming -_pushing_the_limitsAndroid programming -_pushing_the_limits
Android programming -_pushing_the_limits
Droidcon Berlin
 
Paparazzi2
Paparazzi2Paparazzi2
Paparazzi2
Mahmoud
 

Similar to SwiftGirl20170807 - Camera. Photo (20)

Video anomaly detection using Amazon SageMaker, AWS DeepLens, & AWS IoT Green...
Video anomaly detection using Amazon SageMaker, AWS DeepLens, & AWS IoT Green...Video anomaly detection using Amazon SageMaker, AWS DeepLens, & AWS IoT Green...
Video anomaly detection using Amazon SageMaker, AWS DeepLens, & AWS IoT Green...
 
Android UI Tips & Tricks
Android UI Tips & TricksAndroid UI Tips & Tricks
Android UI Tips & Tricks
 
Asynchronous Programming with JavaScript
Asynchronous Programming with JavaScriptAsynchronous Programming with JavaScript
Asynchronous Programming with JavaScript
 
Creating a Facebook Clone - Part XLIII - Transcript.pdf
Creating a Facebook Clone - Part XLIII - Transcript.pdfCreating a Facebook Clone - Part XLIII - Transcript.pdf
Creating a Facebook Clone - Part XLIII - Transcript.pdf
 
Android ui tips & tricks
Android ui tips & tricksAndroid ui tips & tricks
Android ui tips & tricks
 
20150319 testotipsio
20150319 testotipsio20150319 testotipsio
20150319 testotipsio
 
A comprehensive tutorial to upload, cache, save and share image in Android apps
A comprehensive tutorial to upload, cache, save and share image in Android appsA comprehensive tutorial to upload, cache, save and share image in Android apps
A comprehensive tutorial to upload, cache, save and share image in Android apps
 
WebXR if X = how?
WebXR if X = how?WebXR if X = how?
WebXR if X = how?
 
Getting started with rails active storage wae
Getting started with rails active storage waeGetting started with rails active storage wae
Getting started with rails active storage wae
 
Android programming -_pushing_the_limits
Android programming -_pushing_the_limitsAndroid programming -_pushing_the_limits
Android programming -_pushing_the_limits
 
Exploring CameraX from JetPack
Exploring CameraX from JetPackExploring CameraX from JetPack
Exploring CameraX from JetPack
 
Android Oreo
Android OreoAndroid Oreo
Android Oreo
 
QConSP 2015 - Dicas de Performance para Aplicações Web
QConSP 2015 - Dicas de Performance para Aplicações WebQConSP 2015 - Dicas de Performance para Aplicações Web
QConSP 2015 - Dicas de Performance para Aplicações Web
 
Ui perfomance
Ui perfomanceUi perfomance
Ui perfomance
 
Introduction of Android Camera1
Introduction of Android Camera1Introduction of Android Camera1
Introduction of Android Camera1
 
Standford 2015 week5: 1.View Controller Lifecycle, Autolayout 2. Scroll View ...
Standford 2015 week5: 1.View Controller Lifecycle, Autolayout 2. Scroll View ...Standford 2015 week5: 1.View Controller Lifecycle, Autolayout 2. Scroll View ...
Standford 2015 week5: 1.View Controller Lifecycle, Autolayout 2. Scroll View ...
 
Serverless Orchestration with AWS Step Functions - DevDay Los Angeles 2017
Serverless Orchestration with AWS Step Functions - DevDay Los Angeles 2017Serverless Orchestration with AWS Step Functions - DevDay Los Angeles 2017
Serverless Orchestration with AWS Step Functions - DevDay Los Angeles 2017
 
Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)
 
303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code
 
Paparazzi2
Paparazzi2Paparazzi2
Paparazzi2
 

Recently uploaded

TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
anilsa9823
 

Recently uploaded (20)

Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 

SwiftGirl20170807 - Camera. Photo

Editor's Notes

  1. 大家好 今天的主題是卡麥拉·佛托的廣角鏡頭, 就是介紹相機跟照片的基本概念跟應用
  2. 自介, 我叫張筱姍, 大家叫我筱姍就可以了, 因為我很喜歡織毛線, 我目前主要是在開發一些跟織毛線.手作相關的app. 目前已經上架app的只有一個,叫KCCounter, 是編織用的計數器. 因為每天都一個人在家做, 怕會偷懶, 所以我跟我一個好朋友建了這個創業歐北共粉絲團, 每週五會發一篇文章, 記錄一下自己每週做了什麼事情,
  3. 哪些App會用到相機跟照片?社交類的像是instagram
  4. 通訊類的像line
  5. 當然還有專門在做影像編輯的App, 在Appstore上面Apple就有單獨一個分類叫做照片和影片
  6. 這些App幾乎都做的3件事, 拍照. 從手機取出照片. 把照片存到手機. 那我們今天主要就是要學會這3件事情
  7. 因為Apple要保護使用者的隱私, 所以妳的App想要取用使用者的一些東西的時候, Apple規定一定要在專案的info.plist裡面,設定相關的Privacy Usage Description. 我們要用到相機跟照片, 那就要設定Camera跟Photo這兩個, 當我們的app第一次執行到相關的程式的時後, 會跳出像旁邊這樣的視窗問使用者要不要允許, 那我們設的Usage Description文字就會顯示在這個視窗中間, 如果沒設定Usage Description, app在執行的時候就會直接Crash, 你在console就會看到像下面這樣的錯誤訊息
  8. 再來開始進入程式的部分 第一個介紹的是UIImagePickerController, 這個Controller會幫我們產生一個基本簡單的畫面, 讓我們可以進行拍照或是列出照片. 細節他都處理好了, 我們做ㄧ些簡單的設定以後就可以直接用. 那他有2個比較重要的property. 第一個是sourcetype. UIImagePickerController可以產生出拍照或是列出照片的畫面, 那他要知道要用哪個畫面就是用sourcetype來判斷. 有3種可以用. camera相機. photoLibrary所有相簿列表. savedPhotoAlbum所有照片列表. 預設值是photoLibrary. photoLibrary只會列出有照片的相簿, 沒有的不會顯示. 第二個是delegate. delegate一定要包含UIImagePickerControllerDelegate跟UINavigationControllerDelegate這兩種.delegate預設是nil. 沒有設delegate那controller就不能用, 所以這個一定要記得設定
  9. 再來講這個UIImagePickerControllerDelegate. 他主要有2個function可以實作. didFinishPickingMediaWithInfo跟imagePickerControllerDidCancel Demo: didFinishPickingMediaWithInfo就是你拍完照片點use photo 或者是在相簿選一張照片之後會執行這裡.那imagePickerControllerDidCancel就是點取消的時後會執行
  10. Imagepicker能做的事情不多.那我們如果還要對手機的照片做其他事.就要用照片專用的framework.在8.0以前.是要用這個AssetsLibrary. Apple在8.0推出了新的叫Photos.原本這個在9.0就被停用
  11. Photos Framework主要是讓我們可以對照片影片相簿這些東西做新增刪除修改查詢 然後還可以取得照片影片的檔案跟metadata
  12. 這是apple定義在photos framework 裡面的物件架構 最小是asset就是代表一個照片或影片, 他的class是叫phasset. 很多個asset會組成asset collection.列如一個相簿.一個日時刻. 這種的class叫PHAssetCollection. 很多個asset collection會組成collection list例如一個年的時刻, 那這個的class叫PHCollectionList
  13. Photos Framework有兩個比較重要的class, 第一個是PHPhotoLibrary, 它可以用來執行改變, 像新增修改刪除這些動作, 還可以監控改變 另外一個PHImageManager, 則是用來讀取照片影片的檔案
  14. //請求相機權限 AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { granted in print("camera access:\(granted)") }
  15. guard AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo) == .authorized else { print("not authorized....") return } guard UIImagePickerController.isSourceTypeAvailable(.camera) else { print("Camera not available.") return } let controller = UIImagePickerController() controller.sourceType = .camera controller.delegate = self self.present(controller, animated: true, completion: nil)
  16. //請求照片權限 PHPhotoLibrary.requestAuthorization { (status) in switch status { case .authorized: print("authorized..") case .denied: print("denied..") case .notDetermined: print("notDetermined..") case .restricted: print("restricted..") } }
  17. guard PHPhotoLibrary.authorizationStatus() == .authorized else { print("PHPhotoLibrary not available.") return } guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else { print("Camera not available.") return } let controller = UIImagePickerController() controller.sourceType = .photoLibrary controller.delegate = self self.present(controller, animated: true, completion: nil)
  18. func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { print(".....info.....\n\(info)") //從info取出拍好的照片 if let pickedPhoto = info[UIImagePickerControllerOriginalImage] as? UIImage { img.image = pickedPhoto } //把相機畫面關掉 picker.dismiss(animated: true, completion: nil) } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { print("Cancel imagePickerController.”) picker.dismiss(animated: true, completion: nil) }
  19. if picker.sourceType == .camera { //儲存照片至相機膠卷 //1. UIKit method, iOS 2.0+ // UIImageWriteToSavedPhotosAlbum(pickedPhoto, nil, nil, nil) //2. Use Photos Library ,iOS 8.0+ PHPhotoLibrary.shared().performChanges({ PHAssetChangeRequest.creationRequestForAsset(from: pickedPhoto) }, completionHandler: {success, error in if success { print("save success.") } else { print("error creating asset: \(String(describing: error))") } }) }
  20. //取得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)") } }) }
  21. 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))") } } }
  22. //依照相簿名稱取得相簿,不存在則回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 }
  23. 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))") } })