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上传到服务器,此时上传的是一张图片+视频。当展示的时候分以下几种情况:
- 对于苹果手机的用户,可以从服务端获取图片+视频,然后将其合成Live Photo进行展示
- 对于Android手机用户,可以模拟Live Photo,将图片覆盖到视频上,然后进行隐藏展示播放。当播放时隐藏图片,让视频播放;当停止播放时显示图片覆盖视频,停止视频播放
- 对于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中又包含了符合该组条件的图片例如:
左边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的图片+视频:
通过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
LivePhoto开发,你要知道的知识点的更多相关文章
- 学Android开发,入门语言java知识点
学Android开发,入门语言java知识点 Android是一种以Linux为基础的开源码操作系统,主要使用于便携设备,而linux是用c语言和少量汇编语言写成的,如果你想研究Android,就去学 ...
- Android开发涉及有点概念&相关知识点(待写)
前言,承接之前的 IOS开发涉及有点概念&相关知识点,这次归纳的是Android开发相关,好废话不说了.. 先声明下,Android开发涉及概念比IOS杂很多,可能有很多都题不到的.. 首先由 ...
- iOS开发中关于UIImage的知识点总结
UIImage是iOS中层级比较高的一个用来加载和绘制图像的一个类,更底层的类还有 CGImage,以及iOS5.0以后新增加的CIImage.今天我们主要聊一聊UIImage的三个属性: image ...
- 这些HTML、CSS知识点,面试和平时开发都需要 No8-No9(知识点:媒体操作、构建表单)
系列知识点汇总 这些HTML.CSS知识点,面试和平时开发都需要 No1-No4(知识点:HTML.CSS.盒子模型.内容布局) 这些HTML.CSS知识点,面试和平时开发都需要 No5-No7(知识 ...
- 这些HTML、CSS知识点,面试和平时开发都需要 No10-No11(知识点:表格操作、代码编写规则)
系列知识点汇总 1.基础篇 这些HTML.CSS知识点,面试和平时开发都需要 No1-No4(知识点:HTML.CSS.盒子模型.内容布局) 这些HTML.CSS知识点,面试和平时开发都需要 No5- ...
- 这些HTML、CSS知识点,面试和平时开发都需要 No5-No7(知识点:文字设置、设置背景、数据列表)
系列知识点汇总 这些HTML.CSS知识点,面试和平时开发都需要 No1-No4(知识点:HTML.CSS.盒子模型.内容布局) 这些HTML.CSS知识点,面试和平时开发都需要 No5-No7(知识 ...
- 这些HTML、CSS知识点,面试和平时开发都需要 No1-No4(知识点:HTML、CSS、盒子模型、内容布局)
这些HTML.CSS知识点,面试和平时开发都需要 No1-No4 系列知识点汇总 这些HTML.CSS知识点,面试和平时开发都需要 No1-No4(知识点:HTML.CSS.盒子模型.内容布局) ...
- Hybrid App 应用开发中 9 个必备知识点复习(WebView / 调试 等)
前言 我们大前端团队内部 ?每周一练 的知识复习计划继续加油,本篇文章是 <Hybrid APP 混合应用专题> 主题的第二期和第三期的合集. 这一期共整理了 10 个问题,和相应的参考答 ...
- IOS开发涉及有点概念&相关知识点
前言,IOS是基于UNIX的,用C/C+/OC直通系统底层,不想android有个jvm. 首先还是系统架构的分层架构 1.核心操作系统层 Core OS,就是内存管理.文件系统.电源管理等 2.核心 ...
随机推荐
- cmd命令窗口的快速选中复制黏贴
右击"窗口标题栏",选择属性,进入属性面板: 在"选项"面板勾选编辑选项下的"快速编辑模式"; 点击确认. 这时鼠标左键就有了选中功能,可以 ...
- ReentrantLock 实现原理
使用 synchronize 来做同步处理时,锁的获取和释放都是隐式的,实现的原理是通过编译后加上不同的机器指令来实现. 而 ReentrantLock 就是一个普通的类,它是基于 AQS(Abstr ...
- RedirectToAction()转移方式及参数传递
今天在做一个功能的时,使用RedirectToAction()需要从这里传几个参数,从网上查了一下,这样解决.真好. Return RedirectToAction("Index" ...
- 采坑:python base64
需求: 读取文本内容,对字符串进行base64加密 >>> str = 'aaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbbbbbbbbbb\nccc ...
- AbstractQueuedSynchronizer源码分析(ReentrantLock锁的实现)
1. 前言 Java中好多地方用到AbstractQueuedSynchronizer(PS:简称AQS),比如ReentrantLock.线程池,这部分在面试的时候也经常被问到,今天以Reentr ...
- node 调试相关
#0 node 正确的书写方式 为了防止后面出现混乱的各种书写,先来了解一下如何正确书写 node 的名称. 下面使用来自@bitandbang 推文中的图片展示如何正确书写 node 名称. nod ...
- vue和react的介绍
这几年前端框架发展的不错,出了不少框架,像微软自己的knockoutjs,angular,vue和最近比较火的react等,之前我有写过前两者的相关文章,今天主要说一下后两者. 介绍 是一个用于构建用 ...
- 手把手教您将 libreoffice 移植到函数计算平台
LibreOffice 是由文档基金会开发的自由及开放源代码的办公室套件.LibreOffice 套件包含文字处理器.电子表格.演示文稿程序.矢量图形编辑器和图表工具.数据库管理程序及创建和编辑数学公 ...
- [十八]JavaIO之FileReader 和 FileWriter
简介 FileReader FileWriter 都是提供操作文件的便捷类 这两个类的实现非常的简单 原理 回忆下之前的InputStreamReader和OutputStreamWriter Inp ...
- 基于Dockerfile镜像制作的基本操作
一.使用Dockerfile制作镜像 前面的博客中已经介绍了如何基于容器制作镜像,此方法的原理是使用一个正在运行的容器,根据生产所需进行配置更改等操作后,使其满足生产环境,再将这个容器打包制作为镜像, ...