SlideShare a Scribd company logo
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

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...
Amazon Web Services
 
Android UI Tips & Tricks
Android UI Tips & TricksAndroid UI Tips & Tricks
Android UI Tips & Tricks
DroidConTLV
 
Asynchronous Programming with JavaScript
Asynchronous Programming with JavaScriptAsynchronous Programming with JavaScript
Asynchronous Programming with JavaScript
WebF
 
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
ShaiAlmog1
 
Android ui tips & tricks
Android ui tips & tricksAndroid ui tips & tricks
Android ui tips & tricks
Shem Magnezi
 
20150319 testotipsio
20150319 testotipsio20150319 testotipsio
20150319 testotipsio
Kazuaki Matsuo
 
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
Zuaib
 
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
Bishal Khanal
 
Android programming -_pushing_the_limits
Android programming -_pushing_the_limitsAndroid programming -_pushing_the_limits
Android programming -_pushing_the_limitsDroidcon Berlin
 
Exploring CameraX from JetPack
Exploring CameraX from JetPackExploring CameraX from JetPack
Exploring CameraX from JetPack
Hassan Abid
 
Android Oreo
Android OreoAndroid Oreo
Android Oreo
Siddharth Yadav
 
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
Fabio Akita
 
Ui perfomance
Ui perfomanceUi perfomance
Ui perfomance
Cleveroad
 
Introduction of Android Camera1
Introduction of Android Camera1Introduction of Android Camera1
Introduction of Android Camera1
Booch Lin
 
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 ...
彼得潘 Pan
 
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
Amazon Web Services
 
Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)
Alfredo Morresi
 
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
jonmarimba
 
Paparazzi2
Paparazzi2Paparazzi2
Paparazzi2Mahmoud
 

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

2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
Georgi Kodinov
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Globus
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
Donna Lenk
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
takuyayamamoto1800
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Globus
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Globus
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
abdulrafaychaudhry
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Top 7 Unique WhatsApp API Benefits | Saudi Arabia
Top 7 Unique WhatsApp API Benefits | Saudi ArabiaTop 7 Unique WhatsApp API Benefits | Saudi Arabia
Top 7 Unique WhatsApp API Benefits | Saudi Arabia
Yara Milbes
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
Globus
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
ShamsuddeenMuhammadA
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus
 

Recently uploaded (20)

2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Top 7 Unique WhatsApp API Benefits | Saudi Arabia
Top 7 Unique WhatsApp API Benefits | Saudi ArabiaTop 7 Unique WhatsApp API Benefits | Saudi Arabia
Top 7 Unique WhatsApp API Benefits | Saudi Arabia
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
 

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))") } })