列出照片库中的所有 gif 文件

List all gif files in photo library

我有一个要求,用户需要从库中的 gif 文件列表中获取一个 gif。我试图毫无问题地获取图像和视频。但是当我使用 kUTTypeGIF 作为媒体时,它崩溃并出现错误:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'No available types for source 0'

这是我的代码:

#import "ViewController.h"
#import <MobileCoreServices/MobileCoreServices.h>

@interface ViewController ()<UIImagePickerControllerDelegate, UINavigationControllerDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

-(IBAction)btnChooseGif:(id)sender {
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
    imagePicker.delegate = self;
    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    imagePicker.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeGIF, nil];   // Here is the crash 
    [self presentViewController:imagePicker animated:YES completion:nil];
}

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{

}
@end

我该如何解决这个问题?如果此处不支持 kUTTypeGIF 媒体,我如何向用户显示所有 gif 文件列表以供选择?我只需要在 UIImagePickerController

中显示 gif 文件

iOS 没有提供一种简单的方法来确定——在使用 UIImagePickerController 时——相机胶卷中存储的图片的基本文件格式是什么。 Apple 的哲学是图像应该被视为一个 UIImage 对象,你不应该关心最终的文件格式是什么。

所以,既然不能用UIImagePickerController过滤掉GIF文件。这里有几种可能性:

1)

一旦你选择了一张图片,你就可以确定它是什么类型的文件。 Here's an example question that asks how to determine if the image is a PNG or JPEG。一旦用户选择了一个文件,您就会知道它是 GIF 还是 JPEG 或 PNG 还是其他格式。

2)

您可以将任何 UIImage 转换GIF 文件。 Here's a question that points to a library that might be able to help.

3)

您可以遍历整个相机胶卷并将这些图像 convert/save 作为 GIF 文件放入应用的文档目录中。开始 with enumeration found in this related question 然后通过 ImageIO 框架运行每张图片以将其转换为 gif 文件的东西(我在解决方案 # 2 中指出的代码)。然后您可以滚动自己的选择器。

p.s。您自己的代码无法正常工作,因为正如 Nathan 指出的那样,gif 不是一种媒体类型。这是一个指出可用媒体类型的函数:

-(IBAction)btnChooseGif:(id)sender {
    NSArray *availableMedia = [UIImagePickerController availableMediaTypesForSourceType: UIImagePickerControllerSourceTypePhotoLibrary];

    NSLog(@"availableMedia is %@", availableMedia);

    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
    imagePicker.delegate = self;
    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

    imagePicker.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeImage, nil];
    [self presentViewController:imagePicker animated:YES completion:nil];
}

如果您只想从没有选择器的照片库中获取资源,您可以使用 PHFetchResult 获取 PHAsset 的数组。以下是 Photos.Framework 中可用的 MediaType enums 列表:

typedef NS_ENUM(NSInteger, PHAssetMediaType) {
PHAssetMediaTypeUnknown = 0,
PHAssetMediaTypeImage   = 1,
PHAssetMediaTypeVideo   = 2,
PHAssetMediaTypeAudio   = 3,
} PHOTOS_ENUM_AVAILABLE_IOS_TVOS(8_0, 10_0);

您可以将其用作:

PHFetchResult *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];

并从资产请求图片为:

PHImageManager *manager = [PHImageManager defaultManager];

    PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
    requestOptions.resizeMode   = PHImageRequestOptionsResizeModeExact;
    requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
    requestOptions.synchronous = true;

[manager requestImageDataForAsset:asset options:requestOptions resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
 NSLog(@"Data UTI :%@ \t Info :%@",dataUTI,info);
            }];

希望对您有所帮助!!

在iOS11你可以通过智能相册获取所有gif。

func getGif() -> PHFetchResult<PHAsset> {
     if let gifCollection = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumAnimated, options: nil).firstObject {
        return PHAsset.fetchAssets(in: gifCollection, options: nil)
    }
    return PHFetchResult<PHAsset>()
}