#Task-11 照片編輯App - PhotoEditor (01 - 拍照&選擇照片)
這次的作業是要做一個可以編輯照片的 App,會分成 4 篇來介紹,第一篇是總覽 & 拍照、選擇照片
用 Storyboard 製作,使用到的功能或方法:
- AutoLayout、Stack View 排版
- PHPickerViewController、UIImagePickerController 拍照&選照片
- Present、Dismiss 顯示&關閉 controller
- CGAffineTransform 旋轉照片、縮放貼圖及尺寸框
- UIColorPickerViewController 選文字顏色
- UIPanGestureRecognizer、UIPinchGestureRecognizer 拖曳、縮放貼圖及尺寸框
- ScrollView 縮放照片
- PerformSegue、IBSegueAction、Unwind、Prepare 傳輸資料到下一頁、回傳資料到上一頁
- CIFilter:CIColorControls 調整亮度、對比、飽和度的 filter
- CIFilter:CIPhotoEffect- 照片濾鏡 filter
- CAShapeLayer、UIBezierPath 繪製尺寸框
- UIGraphicsImageRenderer 儲存圖片
- UIActivityViewController 分享圖片
- Delegate、Extension
作業一共用到 4 個 View Controller
⭐️ 呈現的畫面:
⭐️ 實現的功能:
- 拍照&選照片
- 旋轉圖片
- 調整照片亮度、對比、飽和度
- 濾鏡效果
- 調整照片比例:正方形、16:9、5:4、7:5、4:3、5:3、3:2
- 縮放圖片
- 在照片上加上文字、貼圖
- 儲存&分享照片
⭐️ 完整操作影片:
⭐️ 拍照功能(僅實機使用,模擬器不能拍照)UIImagePickerController
1. 遵從 UIImagePickerControllerDelegate、UINavigationControllerDelegate
- 查詢 UIImagePickerController 的定義時可以看到裡面的 delegate 如下,所以兩個都要遵從才行
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate{
}
2. 撰寫開啟相機的按鈕的 IBAction function
@IBAction func takePhoto(_ sender: Any) {
let controller = UIImagePickerController()
//sourceType設為.camera代表呼叫controller是用來開啟相機
controller.sourceType = .camera
controller.delegate = self
present(controller, animated: true, completion: nil)
}
3. 設定拍完照後執行的 function imagePickerController(_:didFinishPickingMediaWithInfo:)
//拍照後執行的function
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
//儲存點選的照片資訊的property,利用參數info的.originalImage取得圖片相關資料
let photo = info[.originalImage] as? UIImage
self.coverStackView.isHidden = true
//關閉拍照的controller
dismiss(animated: true) {
//photoImage是我用來儲存拍照或相簿選擇的照片的變數
self.photoImage = photo!
//selectedImageView是用來顯示照片的imageView
self.selectedImageView.image = self.photoImage
self.editButton.isHidden = false
}
}
4. 到 App 的 Info 頁面做隱私權限設定,開啟相機時才不會閃退哦!
點任一 + 號新增 key,選擇 Privacy- Camera Usage Description,然後在 Value 中新增提示語,就可以了!
UIImagePickerController 也可以用來從相簿選擇照片,只要在 sourceType 設定改為 .photoLibrary,不過因為後來出現了更強大的 PHPickerViewController,所以官方已經不建議再使用 UIImagePickerController 來選照片,未來 photoLibrary 也會移除
⭐️ 從相簿選擇照片 PHPickerViewController
1. 使用PHPickerViewController 需要 import PhotosUI
import PhotosUI
2. 遵從 PHPickerViewControllerDelegate
class ViewController: UIViewController, PHPickerViewControllerDelegate{
}
3. 撰寫開啟相簿的按鈕的 IBAction function
@IBAction func selectImage(_ sender: Any) {
var configuration = PHPickerConfiguration()
//PHPickerConfiguration可以設定選擇照片或影片,nil則兩種都可以選擇,我們只要選擇照片,所以設定 .images
configuration.filter = .images
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
present(picker, animated: true, completion: nil)
}
註:PHPickerConfiguration 預設僅能選擇一張照片,因為我做的 App 一次只針對一張照片編輯,所以沒有額外做照片選擇張數的設定。如果要選擇多張照片,可以參考彼得潘的文章⬇︎
4. 設定選擇完照片後執行的 function picker(_:didFinishPicking:)
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
//關閉controller
picker.dismiss(animated: true)
//從 PHPickerResult的itemProvider載入選擇的照片
let itemProviders = results.map(\.itemProvider)
//使用者有可能沒有選擇照片,所以用if let先檢查itemProviders.first裡面有沒有值
if let itemProvider = itemProviders.first, itemProvider.canLoadObject(ofClass: UIImage.self){
//previousImage用來儲存本來imageView顯示的照片,以判斷選擇照片時原本的照片是否還是同一張,如果是才將照片替換成選擇的照片
let previousImage = self.photoImage
self.coverStackView.isHidden = true
//載入照片
itemProvider.loadObject(ofClass: UIImage.self) { [weak self] (image, Error) in
DispatchQueue.main.async {
//判斷照片是否仍是同一張
guard let self = self, let image = image as? UIImage, self.photoImage == previousImage else { return }
//變數photoImage儲存選擇的照片
self.photoImage = image
//imageView顯示選擇的照片
self.selectedImageView.image = self.photoImage
self.editButton.isHidden = false
}
}
}
}
第一篇先介紹到這裡,後面待我繼續補上!最後一篇再寫關於這個作業的心得😭
💡 續集們
#Task-11 照片編輯App- PhotoEditor (04- 尺寸調整&儲存)
這次的作業是要做一個可以編輯照片的 App,會分成 4 篇來介紹,最後一篇是照片尺寸調整&儲存
medium.com
參考資料
使用的素材
Camera vector created by freepik — www.freepik.com
Planner vector created by freepik — www.freepik.com
Note design vector created by rawpixel.com — www.freepik.com