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

来源:https://www.cnblogs.com/zhanggui/archive/2018/07/09/9283428.html
-Advertisement-
Play Games

Live Photo開發,瞭解之後可以將其應用於開發過程中。 ...


前言

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 版權聲明:未經博主允許不得轉載 OrmLite基礎知識 什麼是OrmLite框架,在我沒用這個框架時,不知道它有多好,用了才知道很方便哦,為了提供開發效率,Android開發者需要懂得運行多種框架進行開發。對於OrmLite框架是一種很輕量級的資料庫操作框架,它的底層是由反射機制實現的。 OrmLi ...
  • 前言 大家好,給大家帶來 的概述,希望你們喜歡 每日一句: Success is connecting with the world and making people feel. 《名揚四海》 設計思路 當我們面臨製作登錄和註冊功能的實現時,我們需要先 設計登錄界面的佈局和註冊界面的佈局,做到有完 ...
  • 前言 大家好,給大家帶來 的概述,希望你們喜歡 學習目標 1. 掌握SQLite資料庫的使用,能夠實現用資料庫來保存用戶的信息; 2. 學會運用好個人資料,以及個人資料的修改功能實現; 3. 個人資料包括用戶名,昵稱,性別,簽名,QQ號或個人社交賬號的記錄等。 資料庫的創建 資料庫類 該類繼承 創建 ...
  • //這裡有一個模擬器沙盒路徑(完整路徑) NSString* index=@"/Users/junzoo/Library/Application Support/iPhone Simulator/7.0.3/Applications/63925F20-AF97-4610-AF1C-B6B4157D1 ...
  • "使用AppleDoc快速生成iOS開發文檔 _ 皮卡丘♪~(´ε` )" "用 appledoc 生成文檔 _ Garan no dou" "xcode select_ error_ tool 'xcodebuild' requires Xcode, but active developer di ...
  • 為什麼不使用xml繪製Andoird的UI? 類型不安全 非空不安全 xml迫使你在很多佈局中寫很多相同的代碼 設備在解析xml時會耗費更多的cpu運行時間和電池 最重要的時,它允許任何代碼重用 簡單案例 findViewById() LayoutParams 使用 描述佈局參數,其中寬高都是 設置 ...
  • 添加依賴 Color 不透明的紅色 Dimensions 使用 和`sp dip(dipValue) sp(spValue)` applyRecursively() applyRecursively()應用於lambda表達式的本身,然後遞歸地運用在他的子view 以上表示,該 中的 的`textS ...
  • Alamofire框架的使用一 —— 基本用法 對於使用Objective-C的開發者,一定非常熟悉AFNetworking這個網路框架。在蘋果推出的Swift之後,AFNetworking的作者專門用Swift來編寫一個類似AFNetworking的網路框架,稱為Alamofire。Alamofi ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...