【iOS特性】3D Touch - Live Photo

Live Photo

Live Photo 是一种由苹果公司推出的照片格式,它能够捕捉和展示静态照片之外的动态内容。当用户拍摄一张 Live Photo时,相机会在用户按下快门的瞬间记录几秒钟的视频和音频。这使得照片变得更加生动,用户可以通过长按照片来观看和感受其中的动态内容。

用白话说就是拍照时的实况,拍摄的照片长按预览时可以看到 3秒的视频效果。这里记录一下 Live Photo 的基本使用,末尾附完整示例demo。

Live Photo的拍摄与区分

在这里插入图片描述

拍摄 Live Photo也很简单,打开苹果相机选择 【照片】开启顶部的【实况】按钮即可,拍摄完成后在相册中就可以看到照片左上角会带【实况】标志。

Live Photo的基本使用

从本地获取 Live Photo 主要有3种情况:

  • 系统相册:使用照片选择器 UIImagePickerController直接获取Live Photo 照片
  • 自定义相册:获取照片的资源文件 PHAsset 再转为 Live Photo
  • 本地文件:从本地沙盒或者 main bundle 获取
  • 网络 Live Photo

使用UIImagePickerController

1.导入依赖

#import <Photos/Photos.h>
#import <PhotosUI/PhotosUI.h>
#import <MobileCoreServices/MobileCoreServices.h>

2.请求权限

PHAuthorizationStatus authstatus = [PHPhotoLibrary authorizationStatus];
    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
        if (status == PHAuthorizationStatusAuthorized) {
            //允许使用相册
            dispatch_async(dispatch_get_main_queue(), ^{
                [self chooseMovFromLibrary];
            });
        }else if(authstatus != PHAuthorizationStatusNotDetermined) {
            dispatch_async(dispatch_get_main_queue(), ^{
                ...
            });
        }
    }];

3.实现图片选择协议

 - (void)chooseMovFromLibrary {
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    // 选取live photo
    imagePicker.mediaTypes = @[(NSString *)kUTTypeImage,(NSString *)kUTTypeLivePhoto];
    imagePicker.delegate = self;
    [self presentViewController:imagePicker animated:YES completion:^{}];
}

#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
    // 从选择器返回的信息中获取 Live Photo 对象
    PHLivePhoto *photo = [info objectForKey:UIImagePickerControllerLivePhoto];
    // dismiss 图片选择器界面
    [picker dismissViewControllerAnimated:YES completion:^{
        if (photo) {
            self.livePhotoView.hidden = NO;
            // 将 Live Photo 对象赋值给 PHLivePhotoView 对象,以便显示
             self.livePhotoView.livePhoto = photo;
        }
    }];
}

4.设置播放暂停

Live Photo 有3种播放模式,根据自己需求选择

typedef NS_ENUM(NSInteger, PHLivePhotoViewPlaybackStyle) {
    PHLivePhotoViewPlaybackStyleUndefined = 0, // 不播放
    PHLivePhotoViewPlaybackStyleFull, // 完全播放
    PHLivePhotoViewPlaybackStyleHint, // 预览播放
};
// 设置播放
- (void)playButtonClick {
    [self.livePhotoView startPlaybackWithStyle: PHLivePhotoViewPlaybackStyleFull];
}

// 暂停播放
- (void)stopButtonClick {
    [self.livePhotoView stopPlayback];
}

使用PHAsset转为Live Photo

很多时候我们获取到的会是 PHAsset资源,这时就需要对资源类型进行转换,通过 PHImageManager 的**- (PHImageRequestID)requestLivePhotoForAsset:targetSize:contentMode:options:resultHandler:**转换为 Live Photo

PHFetchOptions *options = [[PHFetchOptions alloc] init];
// 按创建日期降序排列
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
// 获取资产(照片或视频)列表
PHFetchResult *assetsFetchResults = [PHAsset fetchAssetsWithOptions:options];
// 查找一张live photo
__block PHAsset *asset;
[assetsFetchResults enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    if ([obj isKindOfClass: [PHAsset class]]) {
        PHAsset *tmpAsset = (PHAsset*)obj;
        if (tmpAsset.mediaSubtypes == PHAssetMediaSubtypePhotoLive) {
            asset = tmpAsset;
            *stop = YES;
        }
    }
    NSLog(@"%@", obj);
}];
if (asset) {
    // PHAsset 转 live photo
    [[PHImageManager defaultManager] requestLivePhotoForAsset:asset
       targetSize:CGSizeMake(asset.pixelWidth, asset.pixelHeight)
       contentMode:PHImageContentModeAspectFit
       options:nil
       resultHandler:^(PHLivePhoto * _Nullable livePhoto, NSDictionary * _Nullable info) {
        if (livePhoto) {
            self.livePhotoView.hidden = NO;
            // 将获取到的 Live Photo 设置给 PHLivePhotoView
            self.livePhotoView.livePhoto = livePhoto;
        }
    }];
}

本地文件

本地沙盒一般存放的是图片、视频或者json等类型明确的文件,Live Photo 比较特殊,是一张图片加一个 mov 视频,并且该图片和视频必须来自同一张 Live Photo

因此我们需要从沙盒中分别获取到图片和视频的URL地址,然后调用 PHLivePhoto+(PHLivePhotoRequestID)requestLivePhotoWithResourceFileURLs:placeholderImage:targetSize:contentMode:resultHandler:进行获取

- (void)loadLocalFile {
    NSString *imagePath = [self getFilePathWithKey:@"image.jpg"];
    NSString *movPath = [self getFilePathWithKey:@"mov.mov"];
    
    // 创建一个 NSURL 数组,包含 Live Photo 的静态图片和视频文件的 URL
    NSArray *resourceFileURLs = @[
        [NSURL fileURLWithPath:imagePath],
        [NSURL fileURLWithPath:movPath],
    ];

    // 创建一个占位图 UIImage 对象
    UIImage *placeholderImage = [UIImage imageNamed:@"IMG_1232.JPG"];

    // 请求一个 Live Photo 对象
    [PHLivePhoto requestLivePhotoWithResourceFileURLs:resourceFileURLs
                                   placeholderImage:placeholderImage
                                        targetSize:self.livePhotoView.bounds.size
                                       contentMode:PHImageContentModeAspectFill
                                       resultHandler:^(PHLivePhoto * _Nullable livePhoto, NSDictionary * _Nonnull info) {
        if (livePhoto) {
            self.livePhotoView.hidden = NO;
            // 如果成功获取到 Live Photo 对象,则将其赋值给 PHLivePhotoView
            self.livePhotoView.livePhoto = livePhoto;
        }
        // 开始以全屏播放样式播放 Live Photo
        // [self.livePhotoView startPlaybackWithStyle:PHLivePhotoViewPlaybackStyleFull];
    }];
}

网络资源

对于网络的 Live Photo 需要先保存到本地,然后通过 PHPhotoLibrary- (void)performChanges: completionHandler:方法保存到相册。

// 写入相册
NSString *imagePath = [self getFilePathWithKey:@"image.jpg"];
NSString *movPath = [self getFilePathWithKey:@"mov.mov"];
    
PHAuthorizationStatus authstatus = [PHPhotoLibrary authorizationStatus];
if (authstatus == PHAuthorizationStatusAuthorized) { //已经授权
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
       PHAssetCreationRequest * request = [PHAssetCreationRequest creationRequestForAsset];
       [request addResourceWithType:PHAssetResourceTypePhoto fileURL:[NSURL URLWithString:imagePath] options:nil];
       [request addResourceWithType:PHAssetResourceTypePairedVideo fileURL:[NSURL URLWithString:movPath] options:nil];
    } completionHandler:^(BOOL success, NSError * _Nullable error) {
       if (success) {
           NSLog(@"保存成功");
       }
    }];
}

效果图

最后附上两张效果图

在这里插入图片描述

项目链接

代码量有点多,放到了github上,需要的自取

参考

友情提示

见原文:【iOS特性】3D Touch - Live Photo)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值