当前位置: 首页 > 编程笔记 >

iOS中读取照片库及保存图片或视频到照片库的要点解析

毋玺
2023-03-14
本文向大家介绍iOS中读取照片库及保存图片或视频到照片库的要点解析,包括了iOS中读取照片库及保存图片或视频到照片库的要点解析的使用技巧和注意事项,需要的朋友参考一下

读取照片库PhotoLibrary
iOS中如果我们只有一次读取一张图片或者一个视频(或拍一张照片/视频)的需求,那么我们用 UIImagePickerController 就可以搞定。但是很多时候我们需要一次性从PhotoLibrary读取多个照片或者视频,这时候我们就需要另辟蹊径了,好在apple为我们提供了相应的接口
在开始coding之前我们想要认识几个类:
ALAssetsLibrary:代表整个PhotoLibrary,我们可以生成一个它的实例对象,这个实例对象就相当于是照片库的句柄。
ALAssetsGroup:照片库的分组,我们可以通过ALAssetsLibrary的实例获取所有的分组的句柄。
ALAsset:一个ALAsset的实例代表一个资产,也就是一个photo或者video,我们可以通过他的实例获取对应的subnail或者原图等等。
还需要了解的一个东东就是blocks,apple在iOS 4.0以后大量出现了这玩意儿,有使用越来越广的意思,不过这玩意儿确实好用。关于这玩意儿的内容我在这里不多讲,关注我的博客我会细讲。
对于本文的需求,我们读取group和每个asset都是异步的,但是我们现在用blocks我们可以在一个函数里面搞定。所以blocks确实很方便。
下面直接看代码吧:


ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc]init];//生成整个photolibrary句柄的实例    

NSMutableArray *mediaArray = [[NSMutableArray alloc]init];//存放media的数组    

    [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {//获取所有group    

        [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {//从group里面    

            NSString* assetType = [result valueForProperty:ALAssetPropertyType];    

            if ([assetType isEqualToString:ALAssetTypePhoto]) {    

                NSLog(@"Photo");    

            }else if([assetType isEqualToString:ALAssetTypeVideo]){    

                NSLog(@"Video");    

            }else if([assetType isEqualToString:ALAssetTypeUnknown]){    

                NSLog(@"Unknow AssetType");    

            }    

                

            NSDictionary *assetUrls = [result valueForProperty:ALAssetPropertyURLs];    

            NSUInteger assetCounter = 0;    

            for (NSString *assetURLKey in assetUrls) {    

                NSLog(@"Asset URL %lu = %@",(unsigned long)assetCounter,[assetUrls objectForKey:assetURLKey]);    

            }    

                

            NSLog(@"Representation Size = %lld",[[result defaultRepresentation]size]);    

        }];    

    } failureBlock:^(NSError *error) {    

        NSLog(@"Enumerate the asset groups failed.");    

    }];   

保存图片或视频到PhotoLibrary
时文件然后,然后通过临时文件的路径去转存到photo library。
我们直接来看相应的API:


// These methods can be used to add photos or videos to the saved photos album.  

  

// With a UIImage, the API user can use -[UIImage CGImage] to get a CGImageRef, and cast -[UIImage imageOrientation] to ALAssetOrientation.  

- (void)writeImageToSavedPhotosAlbum:(CGImageRef)imageRef orientation:(ALAssetOrientation)orientation completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock;  

  

// The API user will have to specify the orientation key in the metadata dictionary to preserve the orientation of the image  

- (void)writeImageToSavedPhotosAlbum:(CGImageRef)imageRef metadata:(NSDictionary *)metadata completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_1);  

  

// If there is a conflict between the metadata in the image data and the metadata dictionary, the image data metadata values will be overwritten  

- (void)writeImageDataToSavedPhotosAlbum:(NSData *)imageData metadata:(NSDictionary *)metadata completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_1);  

  

- (void)writeVideoAtPathToSavedPhotosAlbum:(NSURL *)videoPathURL completionBlock:(ALAssetsLibraryWriteVideoCompletionBlock)completionBlock;  


前三个都是存图片的,通过参数我们可以发现,第一个使用了我们传进去的方向,第二个可以通过传入image的metadata保留image的metadata,前两个都是把图片转成 CGImageRef 再保存,第三个是传入NSData所以可以完整保留image的信息,同时也有metadata传进去,如果image自带的信息与metadata冲突那metadata会覆盖图片本身所带的metadata。
最后一个是存储视频的API,可以看到参数是一个NSURL,这个只要穿一个本地临时文件的file URL 就好了。
存储图片根据你的需求选择适当的API,比如我们获取到的是UIImage的实例,那么我们用第一个或者第二个比较方便,如果我们从本地临时文件读取image的数据那么我们直接用第三个就比较方便。
下面来一段简单的代码:

- (void)saveImage:(UIImage*)image{  

    ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc]init];  

    [assetsLibrary writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)image.imageOrientation completionBlock:^(NSURL *assetURL, NSError *error) {  

        if (error) {  

            NSLog(@"Save image fail:%@",error);  

        }else{  

            NSLog(@"Save image succeed.");  

        }  

    }];  

}  


保存video就麻烦点了,你需要先把video写入本地文件然后,获取到本地临时文件的路径,然后调用上面的第四个API写入photo library。
关于写入临时文件,我之前写过一篇关于文件读写的文章,可以去看看。
我这里奉上一个把工程资源库的video写入photo library的demo,这样你就可以把video导入模拟器了,方便有些时候测试。
主要代码如下:

- (void)save:(NSString*)urlString{  

    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];  

    [library writeVideoAtPathToSavedPhotosAlbum:[NSURL fileURLWithPath:urlString]  

                                completionBlock:^(NSURL *assetURL, NSError *error) {  

                                    if (error) {  

                                        NSLog(@"Save video fail:%@",error);  

                                    } else {  

                                        NSLog(@"Save video succeed.");  

                                    }  

                                }];  

}  

 类似资料:
  • 我的应用程序(使用SDK小于24)可以使用相机拍照和视频。这些照片和视频可以在应用程序外的图库中查看。SDK 24及以上版本要求FileProvider创建uri,以便将照片或视频保存到多媒体资料中。 在SDK 24之前,我会使用uri和拍照意图: 使用SDK24及更高版本会出现异常: 我想使用FileProvider实现同样的目标(没有例外)。下面的实现可以拍照,但照片不会出现在图库中。我想知道

  • 问题内容: 我正在开发phonegap应用程序,我需要将URL中的图像保存到Device Photo Gallery。 我在Phonegap Api上找不到执行此操作的方法,而且我也没有找到用于此目的的phonegap插件。 我需要它才能与Iphone和Android一起使用 非常感谢! 问题答案: 这是任何人都可以使用的文件下载代码。您只有三个参数可以像这样使用- 1) 网址 2)您要在SD卡中

  • 了解如何将 Apple 照片图库迁移到 Lightroom - Adobe 的全新一体化服务,专为摄影爱好者设计。 准备要进行迁移的 Apple 照片图库 请确保将您要迁移的 Apple 照片图库设置为“系统照片图库”。要将图库设置为“系统照片图库”,请执行以下步骤: 打开 Apple 照片,并在菜单栏中选择偏好设置。 单击通用标签,然后在图库位置下方选择用作系统照片图库。 选择“用作系统照片图库

  • 问题内容: 我想从我的应用程序中的用户照片库访问照片,而我正在查看UIImagePickerController。但是,我想知道是否可以在不将照片实际存储在应用程序中的情况下访问和查看照片库中的照片?因此,基本上,该应用将存储对所选照片的​​引用,而不是存储照片本身。这是为了防止该应用占用大量空间来存储每张照片。 谢谢! 问题答案: 它不是那么简单,但是正如Rob所提到的,您可以保存照片资产url

  • Pinch手势对图片进行缩放。即用两根手指往不同方向拖拉照片,照片会被缩小或放大。 作者说:在本站见到过一些照片缩放的例子,都是用ScrollerView设置的,总感觉有点飘浮。本例子用简单地手势控制照片的缩放。 [Code4App.com]

  • 问题内容: 我需要在活动中获得并显示照片库中最近拍摄的3张照片,而无需任何点击。 完成此步骤后,滚动时,我应该以3 x 3的方式拍摄其他照片。 您知道快速执行此操作的正确方法吗?谢谢。 问题答案: 这是使用适用于iOS 8+设备的框架的解决方案: