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

前言

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

正文

先了解幾個概念。 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上傳到服務器,此時上傳的是一張圖片+視頻。當展現的時候分如下幾種狀況:git

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

接下來分平臺進行操做處理。github

iOS

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

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集合:api

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獲取的:app

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

相關文章
相關標籤/搜索