LivePhoto開發,你要知道的知識點


前言

Apple從iPhone6s開始支持Live Photo。Live Photo 會錄下拍照前后 1.5 秒所發生的一切,因此用戶獲得的不僅僅是一張精美照片,還有拍照前后時刻的動作和聲音。具體的操作可以參見拍照和編輯
本文接下來要介紹的是如何在項目開發過程中使用Live Photo以及兼容其他平台使用Live Photo。這些平台包括iOS、Web和Android。接下來就開始進行介紹。

正文

先了解幾個概念。
HEVC:全稱High Efficiency Video Coding。它是一種高效的視頻編碼,是符合行業標准的下一代視頻編碼技術,繼承自H.264編碼。Apple想要添加新的功能特性,但是當前的H.264已經無法滿足Apple的需求,因此HEVC應運而生。
HEIF:全稱High Efficiency Image File(Format),是一種高效率的圖片文件格式,是中靜止圖像和圖像序列的現代容器格式。
蘋果從iOS11開始已經默認啟動了HEVC電影和HEIF圖像存儲。也就是說iOS11以及以后版本的手機拍攝的圖片默認存儲的格式都是HEIF。但是我們可以嘗試將手機拍攝的圖片發送給其他人,你會發現圖片的格式依然是JPG。這是Apple做了兼容,讓拍攝的照片更好地跨平台支持。但是如果你用Mac上的Photo(應用)將Live Photo以原圖的形式導出,你會發現它導出的內容不再是JPG格式的文件,而是一個HEIC文件+一個mov文件。
Apple其實是通過圖片+視頻的方式實現了Live Photo。
先簡單介紹多平台展示Live Photo的思路:
蘋果手機用戶將Live Photo上傳到服務器,此時上傳的是一張圖片+視頻。當展示的時候分以下幾種情況:

  1. 對於蘋果手機的用戶,可以從服務端獲取圖片+視頻,然后將其合成Live Photo進行展示
  2. 對於Android手機用戶,可以模擬Live Photo,將圖片覆蓋到視頻上,然后進行隱藏展示播放。當播放時隱藏圖片,讓視頻播放;當停止播放時顯示圖片覆蓋視頻,停止視頻播放
  3. 對於Web用戶,可以直接使用Apple官方提供的LivePhotosKit JS,按照其使用方法將圖片和視頻加載到DOM元素中展示。Apple也提供了官方的一個Web展示Live Photo的Demo,點擊這里查看。

接下來分平台進行操作處理。

iOS

首先,我們如果想要手動獲取Live Photo的源文件,蘋果推薦了下面幾種方式:

1.Using macOS Image Capture

  • Connect your iOS device to your Mac.(使用數據線將設備連接到你的Mac)
  • Select the Live Photo you wish to import from your device to your local file system.(選擇你想要導出到你本地文件系統的Live Photo)
  • Choose the destination folder and click on Import.(選擇你的目標文件夾,然后點擊導入)

2.Using macOS Photos

  • Connect your iOS device to your Mac.(將你的iOS設備和Mac相連)
  • Import your photos into the Photos application.(把你手機上的圖片導入到Photos應用程序中)
  • Select the Live Photo you wish to export.(選中你想要導入的Live Photo)
  • Use File > Export > Export Unmodified Original to export to your file system.(導出,選擇導出一張未修改的原件即可)

3.Using Windows 10 File Explorer

  • Ensure that iTunes for Windows is installed. You can download it from here: http://www.apple.com/itunes/download/
  • Open File Explorer. This can be opened by pressing the Windows Key and E at the same time.
  • Connect your iOS device to your PC.
  • You should see your iOS device in the "This PC" folder.
  • Navigate to the following folder: (your device) > Internal Storage > DCIM and look for the Live Photo you wish to import.
  • Your Live Photo will be stored as a pair of files: a JPG file and a MOV file.
  • Drag the pair of files to your local file system.

導出之后,得到了兩個文件:一個是后綴為HEIC的圖像文件,一個是mov后綴的視頻文件。此時,便可以手動將圖片+視頻上傳到Server,然后供其他端使用。
如果是用戶使用自己的iOS設備上傳圖片,我們可以先通過PHAssetCollection或者PHAsset獲取圖片,這里有個demo:我通過PHAsset.fetchAssets(with:photoOptions)可以獲取手機上面所有的圖片。還有一個PHAssetCollection的類,它代表圖庫中的組,例如時刻、用戶創建的相冊或者是smart album。我們可以使用該類獲取所有的smartAlbum集合:

var smartAlbums: PHFetchResult<PHAssetCollection>!   //smart albums

 smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: nil)

這里的.smartAlbum就是圖庫中的組的集合,是一個枚舉:

public enum PHAssetCollectionType : Int {
    case album
    case smartAlbum
    case moment
}

此時拿到的smartAlbums就是一組group,每個group中又包含了符合該組條件的圖片例如:
Demo頁面展示
左邊Smart Albums是獲取到的smartAlbums,里面對圖片做了智能分類,包括最近刪除的、屏幕快照、Live Photos、Videos等等。右邊是點擊Live Photos進入的頁面。里面全部是Live Photo。圖片縮略圖頁面的數據是通過上一個頁面傳入的group中單個collection:

  imgListVC.photosList = PHAsset.fetchAssets(in: smartAlbums.object(at: indexPath.row), options: nil)

這里的PHAsset.fetchAssets是從某個PHAssetCollection中獲取該Collection中的所有圖片集合,返回結果:

var photosList: PHFetchResult<PHAsset>? = nil

也就是PHFetchResult類型,是一個結果集。拿到結果集之后,便可以在圖片列表頁面展示:

  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let collectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: CellIdentifier, for: indexPath) as! ImageCollectionCell
        
        let asset = photosList?.object(at: indexPath.row)
        if (asset?.mediaSubtypes.contains(.photoLive))! {
            collectionViewCell.badgeImage = PHLivePhotoView.livePhotoBadgeImage(options: .overContent)
        }
        imageManager.requestImage(for: asset!, targetSize: CGSize.init(width: 80, height: 80), contentMode: .aspectFill, options: nil, resultHandler: { image, _ in
            // The cell may have been recycled by the time this handler gets called;
            // set the cell's thumbnail image only if it's still showing the same asset.
           collectionViewCell.smallImage = image
        })
        
        return collectionViewCell
    }

這里使用的UICollectionView充當容器。collectionViewCell.badgeImage(自定義的image,用於展示左上角的live photo標識)的獲取方式很獨特,是PhotosUI中自帶的API獲取的:

PHLivePhotoView.livePhotoBadgeImage(options: .overContent)

PHLivePhotoView是繼承與UIview的一個子類,可以把它理解為UIImageView,只不過UIImageView是用於展示靜態圖片,而PHLivePhotoView用於展示Live Photo。該類有一個livePhotoBadgeImage的方法用於獲取live photo的標識圖片,選項.overContent是Live Photo正常展示的角標,而.liveOff則是在角標上添加了斜杠,可自行嘗試。
接下來就是獲取要展示的圖片,這里使用到了PHCachingImageManager類,該類主要是提供用於檢索或者生成預覽圖像。所以展示的預覽圖就是通過該類生成的。調用它的requestImage方法,將asset傳入,便可獲UIImage對象。
當點擊某個圖片進去詳情頁面時,通過傳入的asset便可獲取Live Photo,並在PHLivePhotoView上展示:

 PHImageManager.default().requestLivePhoto(for: asset, targetSize: view.frame.size, contentMode: .aspectFit, options: options) { (livePhoto, info) in
            guard livePhoto != nil else {return}
            self.livePhotoImageView.livePhoto = livePhoto
            
        }

這里使用的是PHImageManager,可以通過該類獲取 PHLivePhoto對象。

寫了這么多,只是從相冊中獲取了Live Photo,然后將其展示。那如何獲取該Live Photo的源文件呢?很簡單,直接看下面代碼:

  @objc func getSourceAction() {
        let arr = PHAssetResource.assetResources(for: asset)
        let manager = PHAssetResourceManager.default()
        let resourceReqOptions = PHAssetResourceRequestOptions.init()
        manager.requestData(for: arr[0], options: resourceReqOptions, dataReceivedHandler: { (data) in
            let image = UIImage.init(data: data, scale: 1)
            print(image ?? "沒有圖片")
        }) { (error) in
            print(error?.localizedDescription ?? "err")
        }
        print(arr)
    }

這是點擊獲取資源觸發的Action操作,主要用到了PHAssetResource和PHAssetResourceManager。
PHAssetResource是於照片庫中的圖片視頻或者Live Photo 相關連的底層數據資源,也就是說我可以通過此類獲取Live Photo的圖片+視頻:
PHAssetResource解釋
通過PHAsset獲取asset 資源數組,對Live Photo而言,數組包含了圖片+視頻。這樣如果用戶是通過iOS設備上傳Live Photo,開發者可以獲取到視頻和圖片分別上傳。然后其他端通過使用圖片+視頻模擬Live Photo的展示。
還有一個問題,如果是iOS設備上,如何將網絡獲取的圖片+視頻展示位Live Photo呢?
既然Apple提供了API讓開發者獲取Live Photo的原始資源,也可以通過原始資源合成Live Photo:

    open class func request(withResourceFileURLs fileURLs: [URL], placeholderImage image: UIImage?, targetSize: CGSize, contentMode: PHImageContentMode, resultHandler: @escaping (PHLivePhoto?, [AnyHashable : Any]) -> Swift.Void) -> PHLivePhotoRequestID

此方法是PHLivePhoto的類方法,作用是根據提供的資源文件異步合成Live Photo。這個方法中的URL為一個數組,內容為使用Photos庫導出的Live Photo的源文件(HEIC+mov)。

將生成的Live Photo保存到本地

直接看代碼:

    PHPhotoLibrary.shared().performChanges({
            let request = PHAssetCreationRequest.forAsset()
            let options = PHAssetResourceCreationOptions.init()
            let imageUrl = Bundle.main.path(forResource: "livephoto1", ofType: "HEIC")!
            let vidoUrl = Bundle.main.path(forResource: "livephoto1", ofType: "mov")!
            request.addResource(with: .pairedVideo, fileURL: URL.init(fileURLWithPath: vidoUrl), options: options)
            request.addResource(with: .photo, fileURL: URL.init(fileURLWithPath: imageUrl), options: options)
        }) { (boo, error) in
            if boo {
                print("保存到手機成功")
            }else {
                print(error?.localizedDescription ?? "error")
            }
        }

這里主要使用的是PHAssetCreationRequest類。這里要注意一點,那就是LivePhoto的視頻添加時, PHAssetResourceType為pairedVideo,這種類型是提供Live Photo原始視頻數據的格式。通過add操作之后,可以將合成的Live Photo保存到手機中。
按照上述的方式,便可以在iOS平台上面去使用Live Photo。

Android

Android本身不支持Live Photo,但是可以進行模擬。先從服務端拉取要展示的圖片+視頻,展示時,直接將圖片覆蓋到視頻上,當進行按壓時,隱藏圖片,播放視頻即可。

Web

Apple為了做在線播放Live Photo,官方開發了一套LivePhotoKit的js,通過該JS,開發者可以很容易地將圖片+視頻合稱為Live Photo展示到網頁中。這里是Apple官方提供的Demo。自己有按照LivePhotoKit的指南去開發,但是發現兼容性並不是很好,在Safari中展示沒有什么問題,但是在Chrome和Firefox上展示提示播放失敗。這里后續有待進一步研究。另外,在Web展示的時候如果你使用的外鏈圖片和視頻,容易產生跨域問題:

 No 'Access-Control-Allow-Origin' header 

所以最好通過自己在本地起一個服務,然后同源進行操作。具體的LivePhotoKit使用可以直接查看官方網站的使用。

結束

LivePhoto本質上就是圖片+視頻生成的一種新的照片格式。在對其進行操作的過程中主要用到的Photos+PhotosUI。
代碼Demo可參見這里

如有什么疑問,可留言咨詢!

參考鏈接

1.LivePhotosKit JS
2.Example app using Photos framework
3.Live Photo Editing and RAW Processing with Core Image
4.Working with HEIF and HEVC
5.PHAssetResourceManager usage?
6.拍攝和編輯livephoto
7.FLLivePhotoDemo
8.Live Photo存儲與應用
9.iOS開發創建合成一張LivePhoto


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM