iT邦幫忙

2022 iThome 鐵人賽

0
tags: 釣魚術 swift 拍照

前情提要

  • 昨天根據想像,畫出來的設計,有個新增郵票按鈕
  • 開郵票的時候,首先要開啟相機
  • 擷取圖片確認後,才會進到編輯模式
  • 編輯過程中,選擇(新開 or 舊有)郵票
  • 把文字和圖片存起來,並且同步到雲上

相機功能實作與參考資料

  • 由 Apple Developer 網站提供的範例 Capturing and Saving a Photo
  • 根據上面連結的手法,列出了大致流程,我們先來看看原文寫了什麼

快門簾控制 (Responding to the Shutter Button)

  1. When you tap or click the shutter button in your camera view, things start happening!
  2. The button springs into action, grabs the model’s camera object, then calls its takePhoto() method. Keep going to find out how it takes a photo!

    大致的意思是,步驟一要先開啟相機,所以弄了一個按鈕出來,綁定 takePhoto() 就可以開啟相機啦

捕捉相片

  1. When you take a photo, you want to capture an image with the highest possible resolution. This contrasts with the preview images, which tend to have a lower resolution to facilitate rapidly updating previews in the viewfinder. Your camera has a special photo output that its takePhoto() method uses to capture high-resolution images of what you see in the viewfinder.

    這邊討論的是取景階段時(開啟鏡頭,喬位置、等被攝物擺好姿勢的這個階段),會即時的取圖、呈現、取圖、呈現,相機匯流排(bus)的頻寬有限,一秒預覽好幾格的狀態下,不可能每一幀圖都是最高解析度,所以只有在拍下照片的那個當下才會擷取最大解析度。

  2. You start the real work of taking the photo by requesting the photo output to capture a photo. If all goes well, this is when you hear a reassuring shutter sound to let you — and anyone nearby — know that you’ve just taken a photo.

    拍照成功好的提示聲音

  3. You might wonder why capturePhoto doesn’t just return the photo. That’s because capturing a photo takes time: the camera may need to focus, or wait for the flash, and then there’s the exposure time. The capturePhoto method is asynchronous, with the captured photo typically arriving a short time after you tap or click the shutter button.

    打開快門簾後,需要根據光圈、感光度、補償值等因素去測光,算出的合理曝光時間,並且開始曝一段時間。所以當觸發拍照的動作,有可能會等待數秒後,才能拿到回傳結果圖片。這幾秒鐘如果都站在原地等待,就浪費啦。
    我對於非同步的解釋就好似你去買晚餐,跟水餃店點好 20 顆韭菜水餃,老闆還在下水餃的時候,你如果看到隔壁在賣你想喝的飲料而且還不用排隊,為何不順便去買個飲料,等等再回來拿水餃呢?

  4. After the photo capture has completed, you receive a callback to another method in your camera object: photoOutput(_:didFinishProcessingPhoto:error:). Its first argument receives the captured photo as an instance of AVCapturePhoto.

    透過回呼函數 (callback function) 來繼續後續的行為
    回呼函數真的是一個神奇的東西,字面上包含了回傳和呼叫、回傳時呼叫

    辣個,在場的流露麵我買單、幫我打統編
    打統編就是老闆你牛肉麵做好了之後,要找我拿錢,“打統編” 就是回呼函數啦!!

  5. Now that you’ve got the captured photo, you add it into the camera’s photo stream. It’s then available to any object in your app waiting for a photo, like the data model.

    水餃好囉!!幫你裝到 output 裡了!!

處理與儲存相片

  1. Your data model is patiently awaiting newly-captured photos. Just as for preview images, it has a dedicated task for handling the captured photo stream from the camera, using its handleCameraPhotos method.
  2. Each AVCapturePhoto element in the camera’s photoStream may contain several images at different resolutions, as well as other metadata about the image, such as its size and the date and time the image was captured. You have to unpack it to get the images and metadata that you want. The first thing you do in handleCameraPhotos is to convert photoStream into a more useful unpackedPhotoStream, in which each element is an instance of the PhotoData structure that contains the data you want.
  3. To unpack the photoStream, you’ll use the unpackPhoto(_:) function, which takes a captured photo and returns a PhotoData instance that contains a low-resolution image thumbnail as an Image, the size of the image thumbnail, a high-resolution image as Data, and the size of the high-resolution image.
  4. You’ll recall that, as an asynchronous stream, photoStream is very much like a Sequence. You can use its compactMap(:) method to call unpackPhoto(:) for each photo ($0) in the stream. This transforms the stream of AVCapturePhoto instances into a much more useful stream of PhotoData instances.
  5. The for-await loop now waits for a photoData element to arrive in your unpacked stream before processing it.
  6. You use the thumbnail image in photoData to update your model’s thumbnailImage property.
  7. Call your model’s savePhoto(imageData:) method to save the image data from photoData as a new photo in your photo library.
  8. The savePhoto(imageData:) method creates a task and passes on the real work of saving the photo data to the photoCollection object by calling its addImage(_:) method. And that’s fine! The data model’s job is to coordinate data flow between the app’s data objects.

心得

  • 大致掃了一遍這邊的解釋
  • 部分我不確定語意的部分,會在實作一遍後,把我的認知更新上來。

昨天的設計圖


上一篇
【Day 31】集郵冊:功能規劃與需求分析
下一篇
【Day 33】集郵冊:GridView / LazyVGrid 製作集郵冊排版
系列文
無法成為釣魚大師也要努力摸魚!!辣個吃魚神器 APP38
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言