LivePhoto開發(fā)守屉,你要知道的知識(shí)點(diǎn)

前言

Apple從iPhone6s開始支持Live Photo拦英。Live Photo 會(huì)錄下拍照前后 1.5 秒所發(fā)生的一切,因此用戶獲得的不僅僅是一張精美照片院峡,還有拍照前后時(shí)刻的動(dòng)作和聲音兴使。具體的操作可以參見拍照和編輯
本文接下來要介紹的是如何在項(xiàng)目開發(fā)過程中使用Live Photo以及兼容其他平臺(tái)使用Live Photo照激。這些平臺(tái)包括iOS发魄、Web和Android。接下來就開始進(jìn)行介紹。

正文

先了解幾個(gè)概念励幼。
HEVC:全稱High Efficiency Video Coding汰寓。它是一種高效的視頻編碼,是符合行業(yè)標(biāo)準(zhǔn)的下一代視頻編碼技術(shù)苹粟,繼承自H.264編碼有滑。Apple想要添加新的功能特性,但是當(dāng)前的H.264已經(jīng)無法滿足Apple的需求嵌削,因此HEVC應(yīng)運(yùn)而生毛好。
HEIF:全稱High Efficiency Image File(Format),是一種高效率的圖片文件格式苛秕,是中靜止圖像和圖像序列的現(xiàn)代容器格式睛榄。
蘋果從iOS11開始已經(jīng)默認(rèn)啟動(dòng)了HEVC電影和HEIF圖像存儲(chǔ)。也就是說iOS11以及以后版本的手機(jī)拍攝的圖片默認(rèn)存儲(chǔ)的格式都是HEIF想帅。但是我們可以嘗試將手機(jī)拍攝的圖片發(fā)送給其他人,你會(huì)發(fā)現(xiàn)圖片的格式依然是JPG啡莉。這是Apple做了兼容港准,讓拍攝的照片更好地跨平臺(tái)支持。但是如果你用Mac上的Photo(應(yīng)用)將Live Photo以原圖的形式導(dǎo)出咧欣,你會(huì)發(fā)現(xiàn)它導(dǎo)出的內(nèi)容不再是JPG格式的文件浅缸,而是一個(gè)HEIC文件+一個(gè)mov文件。
Apple其實(shí)是通過圖片+視頻的方式實(shí)現(xiàn)了Live Photo魄咕。
先簡(jiǎn)單介紹多平臺(tái)展示Live Photo的思路:
蘋果手機(jī)用戶將Live Photo上傳到服務(wù)器衩椒,此時(shí)上傳的是一張圖片+視頻。當(dāng)展示的時(shí)候分以下幾種情況:

  1. 對(duì)于蘋果手機(jī)的用戶哮兰,可以從服務(wù)端獲取圖片+視頻毛萌,然后將其合成Live Photo進(jìn)行展示。
  2. 對(duì)于Android手機(jī)用戶喝滞,可以模擬Live Photo阁将,將圖片覆蓋到視頻上,然后進(jìn)行隱藏展示播放右遭。 當(dāng)播放時(shí)隱藏圖片做盅,讓視頻播放;當(dāng)停止播放時(shí)顯示圖片覆蓋視頻窘哈,停止視頻播放吹榴。
  3. 對(duì)于Web用戶,可以直接使用Apple官方提供的LivePhotosKit JS滚婉,按照其使用方法將圖片和視頻加載到DOM元素中展示图筹。Apple也提供了官方的一個(gè)Web展示Live Photo的Demo,點(diǎn)擊這里查看满哪。

接下來分平臺(tái)進(jìn)行操作處理婿斥。

iOS

首先劝篷,我們?nèi)绻胍謩?dòng)獲取Live Photo的源文件,蘋果推薦了下面幾種方式:

1.Using macOS Image Capture

  • Connect your iOS device to your Mac.(使用數(shù)據(jù)線將設(shè)備連接到你的Mac)
  • Select the Live Photo you wish to import from your device to your local file system.(選擇你想要導(dǎo)出到你本地文件系統(tǒng)的Live Photo)
  • Choose the destination folder and click on Import.(選擇你的目標(biāo)文件夾民宿,然后點(diǎn)擊導(dǎo)入)

2.Using macOS Photos

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

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.

導(dǎo)出之后,得到了兩個(gè)文件:一個(gè)是后綴為HEIC的圖像文件活鹰,一個(gè)是mov后綴的視頻文件哈恰。此時(shí),便可以手動(dòng)將圖片+視頻上傳到Server志群,然后供其他端使用着绷。
如果是用戶使用自己的iOS設(shè)備上傳圖片,我們可以先通過PHAssetCollection或者PHAsset獲取圖片锌云,這里有個(gè)demo:我通過PHAsset.fetchAssets(with:photoOptions)可以獲取手機(jī)上面所有的圖片荠医。還有一個(gè)PHAssetCollection的類,它代表圖庫(kù)中的組桑涎,例如時(shí)刻彬向、用戶創(chuàng)建的相冊(cè)或者是smart album。我們可以使用該類獲取所有的smartAlbum集合:

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

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

這里的.smartAlbum就是圖庫(kù)中的組的集合攻冷,是一個(gè)枚舉:

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

此時(shí)拿到的smartAlbums就是一組group娃胆,每個(gè)group中又包含了符合該組條件的圖片例如:


Demo頁(yè)面展示

左邊Smart Albums是獲取到的smartAlbums,里面對(duì)圖片做了智能分類等曼,包括最近刪除的里烦、屏幕快照、Live Photos禁谦、Videos等等胁黑。右邊是點(diǎn)擊Live Photos進(jìn)入的頁(yè)面。里面全部是Live Photo州泊。圖片縮略圖頁(yè)面的數(shù)據(jù)是通過上一個(gè)頁(yè)面?zhèn)魅氲膅roup中單個(gè)collection:

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

這里的PHAsset.fetchAssets是從某個(gè)PHAssetCollection中獲取該Collection中的所有圖片集合别厘,返回結(jié)果:

var photosList: PHFetchResult<PHAsset>? = nil

也就是PHFetchResult類型,是一個(gè)結(jié)果集拥诡。拿到結(jié)果集之后触趴,便可以在圖片列表頁(yè)面展示:

  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充當(dāng)容器。collectionViewCell.badgeImage(自定義的image渴肉,用于展示左上角的live photo標(biāo)識(shí))的獲取方式很獨(dú)特冗懦,是PhotosUI中自帶的API獲取的:

PHLivePhotoView.livePhotoBadgeImage(options: .overContent)

PHLivePhotoView是繼承與UIview的一個(gè)子類,可以把它理解為UIImageView仇祭,只不過UIImageView是用于展示靜態(tài)圖片披蕉,而PHLivePhotoView用于展示Live Photo。該類有一個(gè)livePhotoBadgeImage的方法用于獲取live photo的標(biāo)識(shí)圖片,選項(xiàng).overContent是Live Photo正常展示的角標(biāo),而.liveOff則是在角標(biāo)上添加了斜杠没讲,可自行嘗試眯娱。
接下來就是獲取要展示的圖片,這里使用到了PHCachingImageManager類爬凑,該類主要是提供用于檢索或者生成預(yù)覽圖像徙缴。所以展示的預(yù)覽圖就是通過該類生成的。調(diào)用它的requestImage方法嘁信,將asset傳入于样,便可獲UIImage對(duì)象。
當(dāng)點(diǎn)擊某個(gè)圖片進(jìn)去詳情頁(yè)面時(shí)潘靖,通過傳入的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對(duì)象卦溢。

寫了這么多糊余,只是從相冊(cè)中獲取了Live Photo,然后將其展示单寂。那如何獲取該Live Photo的源文件呢啄刹?很簡(jiǎn)單,直接看下面代碼:

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

這是點(diǎn)擊獲取資源觸發(fā)的Action操作凄贩,主要用到了PHAssetResource和PHAssetResourceManager。
PHAssetResource是于照片庫(kù)中的圖片視頻或者Live Photo 相關(guān)連的底層數(shù)據(jù)資源袱讹,也就是說我可以通過此類獲取Live Photo的圖片+視頻:


PHAssetResource解釋

通過PHAsset獲取asset 資源數(shù)組疲扎,對(duì)Live Photo而言,數(shù)組包含了圖片+視頻捷雕。這樣如果用戶是通過iOS設(shè)備上傳Live Photo椒丧,開發(fā)者可以獲取到視頻和圖片分別上傳。然后其他端通過使用圖片+視頻模擬Live Photo的展示救巷。
還有一個(gè)問題壶熏,如果是iOS設(shè)備上,如何將網(wǎng)絡(luò)獲取的圖片+視頻展示位Live Photo呢浦译?
既然Apple提供了API讓開發(fā)者獲取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的類方法,作用是根據(jù)提供的資源文件異步合成Live Photo精盅。這個(gè)方法中的URL為一個(gè)數(shù)組帽哑,內(nèi)容為使用Photos庫(kù)導(dǎo)出的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("保存到手機(jī)成功")
            }else {
                print(error?.localizedDescription ?? "error")
            }
        }

這里主要使用的是PHAssetCreationRequest類叹俏。這里要注意一點(diǎn)妻枕,那就是LivePhoto的視頻添加時(shí), PHAssetResourceType為pairedVideo,這種類型是提供Live Photo原始視頻數(shù)據(jù)的格式屡谐。通過add操作之后述么,可以將合成的Live Photo保存到手機(jī)中。
按照上述的方式愕掏,便可以在iOS平臺(tái)上面去使用Live Photo度秘。

Android

Android本身不支持Live Photo,但是可以進(jìn)行模擬亭珍。先從服務(wù)端拉取要展示的圖片+視頻敷钾,展示時(shí),直接將圖片覆蓋到視頻上肄梨,當(dāng)進(jìn)行按壓時(shí)阻荒,隱藏圖片,播放視頻即可众羡。

Web

Apple為了做在線播放Live Photo侨赡,官方開發(fā)了一套LivePhotoKit的js,通過該JS粱侣,開發(fā)者可以很容易地將圖片+視頻合稱為L(zhǎng)ive Photo展示到網(wǎng)頁(yè)中羊壹。這里是Apple官方提供的Demo。自己有按照LivePhotoKit的指南去開發(fā)齐婴,但是發(fā)現(xiàn)兼容性并不是很好油猫,在Safari中展示沒有什么問題,但是在Chrome和Firefox上展示提示播放失敗柠偶。這里后續(xù)有待進(jìn)一步研究情妖。另外,在Web展示的時(shí)候如果你使用的外鏈圖片和視頻诱担,容易產(chǎn)生跨域問題:

 No 'Access-Control-Allow-Origin' header 

所以最好通過自己在本地起一個(gè)服務(wù)毡证,然后同源進(jìn)行操作。具體的LivePhotoKit使用可以直接查看官方網(wǎng)站的使用蔫仙。

結(jié)束

LivePhoto本質(zhì)上就是圖片+視頻生成的一種新的照片格式料睛。在對(duì)其進(jìn)行操作的過程中主要用到的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存儲(chǔ)與應(yīng)用
9.iOS開發(fā)創(chuàng)建合成一張LivePhoto

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末施籍,一起剝皮案震驚了整個(gè)濱河市阱州,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌法梯,老刑警劉巖苔货,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件犀概,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡夜惭,警方通過查閱死者的電腦和手機(jī)姻灶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诈茧,“玉大人产喉,你說我怎么就攤上這事「一幔” “怎么了曾沈?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)鸥昏。 經(jīng)常有香客問我塞俱,道長(zhǎng),這世上最難降的妖魔是什么吏垮? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任障涯,我火速辦了婚禮,結(jié)果婚禮上膳汪,老公的妹妹穿的比我還像新娘唯蝶。我一直安慰自己,他們只是感情好遗嗽,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布粘我。 她就那樣靜靜地躺著,像睡著了一般痹换。 火紅的嫁衣襯著肌膚如雪征字。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天晴音,我揣著相機(jī)與錄音,去河邊找鬼缔杉。 笑死锤躁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的或详。 我是一名探鬼主播系羞,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼霸琴!你這毒婦竟也來了椒振?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤梧乘,失蹤者是張志新(化名)和其女友劉穎澎迎,沒想到半個(gè)月后庐杨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡夹供,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年灵份,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哮洽。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡填渠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鸟辅,到底是詐尸還是另有隱情氛什,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布匪凉,位于F島的核電站枪眉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏洒缀。R本人自食惡果不足惜瑰谜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望树绩。 院中可真熱鬧萨脑,春花似錦、人聲如沸饺饭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘫俊。三九已至鹊杖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扛芽,已是汗流浹背骂蓖。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留川尖,地道東北人登下。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像叮喳,于是被迫代替她去往敵國(guó)和親被芳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1馍悟、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽明先生_x閱讀 15,968評(píng)論 3 119
  • 無聊的時(shí)候刷刷電視劇锣咒,發(fā)現(xiàn)每一部韓劇都無恥地撩著老夫的少女心侵状,老公都不知道換了幾任了赞弥,男朋友至今未找到…… 為什么...
    迎刃閱讀 721評(píng)論 4 11
  • 這幾天氣溫開始下降,寒氣襲來壹将! 11月嗤攻,是個(gè)告別月!秋風(fēng)吹诽俯,一地落葉飄妇菱。 夢(mèng)想開始的地方,用腳步丈量暴区。 君が好きだ...
    城市漫步者赤焰龍閱讀 152評(píng)論 2 1
  • 第一篇 人格影響10例 點(diǎn)子1 角色定位法——“生旦凈末丑”的定位 社會(huì)的進(jìn)步闯团、教育的發(fā)展,使班主任的角色從單一走...
    張景丹閱讀 889評(píng)論 0 1