如何正确检测 PHAsset 的文件类型 (GIF)

Posted

技术标签:

【中文标题】如何正确检测 PHAsset 的文件类型 (GIF)【英文标题】:How to properly detect a PHAsset's file type (GIF) 【发布时间】:2016-05-23 00:55:22 【问题描述】:

我不知道为什么这么难。我正在尝试确定 PHAsset 的文件类型,具体来说,我想知道给定的资产是否代表 GIF 图像。

只需检查资产的文件名就知道它是 MP4:

[asset valueForKey:@"filename"] ==> "IMG_XXXX.MP4"

保存到设备图像库时,ios 是否会将 GIF 转换为视频?我也尝试过获取图像的数据并查看它的 dataUTI,但它只为 GIF 返回nil(我假设所有视频也是如此)。我正在按如下方式获取图像数据:

PHImageManager *manager = asset.imageManager ? asset.imageManager : [PHImageManager defaultManager];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^

    PHImageRequestOptions *o = [[PHImageRequestOptions alloc] init];
    o.networkAccessAllowed = YES;

    [manager requestImageDataForAsset:asset.asset options:o resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) 

        dispatch_async(dispatch_get_main_queue(), ^
            CIImage *ciImage = [CIImage imageWithData:imageData];
            if(completion) completion(imageData, dataUTI, orientation, info, ciImage.properties);
        );

    ];

);

上述调用返回的dataUTI是nil

如果有人知道确定 PHAsset 文件类型的可靠方法(我专门寻找 GIF,但能够确定任何类型的文件会很棒),请告诉我!

【问题讨论】:

你找到答案了吗? 你找到答案了吗? 【参考方案1】:

使用 PHAssetResource。

    NSArray *resourceList = [PHAssetResource assetResourcesForAsset:asset];
    [resourceList enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) 
        PHAssetResource *resource = obj;
        if ([resource.uniformTypeIdentifier isEqualToString:@"com.compuserve.gif"]) 
           isGIFImage = YES;
        
    ];

【讨论】:

【参考方案2】:

您还可以从PHContentEditingInput 类中找到uniformTypeIdentifier。为了这;使用 PHAsset 中的 requestContentEditingInput 函数

别忘了 为 kUTTypeGif 导入 MobileCoreServices

Swift 3.1 代码示例:

    let options = PHContentEditingInputRequestOptions()
    options.isNetworkAccessAllowed = true //for icloud backup assets

    let asset : PHAsset = .....  //sampleAsset
    asset.requestContentEditingInput(with: options)  (contentEditingInput, info) in
        if let uniformTypeIdentifier = contentEditingInput?.uniformTypeIdentifier 

            if uniformTypeIdentifier == (kUTTypeGIF as String) 
                debugPrint("This asset is a GIF?")
            

        
    

【讨论】:

这似乎不适用于 Photos.app 编辑扩展。我只在会话开始时通过了PHContentEditingInput(不是资产本身),属性uniformTypeIdentifiernil... 这似乎有点笨拙,因为这个函数请求实际的图像/视频并准备编辑。而且它是异步的,这表明它需要一些时间/资源来执行。【参考方案3】:

适用于 Swift 3.0 及以上版本

import MobileCoreServices


var isGIFImage = false
if let identifier = asset.value(forKey: "uniformTypeIdentifier") as? String

  if identifier == kUTTypeGIF as String
  
    isGIFImage = true
  

【讨论】:

这是公钥吗?【参考方案4】:

我猜从 iOS 11 开始,我们可以使用:

if asset.playbackStyle == .imageAnimated 
    // try to show gif animation

【讨论】:

// 尝试显示 gif 动画 【参考方案5】:

首先,我不确定您所说的 GIF 图片是什么意思。 您指的是实时照片还是延时摄影?

但是,如果您要检查当前资产是 Live Photo、Time-lapse,那么您可以像这样检查

if(asset.mediaSubtypes == PHAssetMediaSubtypePhotoLive)

     // this is a Live Photo


if(asset.mediaSubtypes == PHAssetMediaSubtypeVideoTimelapse)

     // this is a Time-lapse

要确定 PHAsset 的通用文件类型,您可以检查

   asset.mediaType == PHAssetMediaTypeImage 
   asset.mediaType == PHAssetMediaTypeVideo
   asset.mediaType == PHAssetMediaTypeAudio

【讨论】:

他指的是 .gif 格式的图像(动画图像),而不是实况照片或延时摄影。 .png、.jpg、.gif、.tiff 是所有类型的图像。 iOS 上的照片可以存储 gif,他问的是如何检测图像是否为 gif。【参考方案6】:
//phAsset if object of phAsset

if let imageType = phAsset.value(forKey: "uniformTypeIdentifier") as? String 
    if imageType == kUTTypeGIF as String  
        //enter code here
    

【讨论】:

请提供一些解释,以便我们清楚地看到您的意图。

以上是关于如何正确检测 PHAsset 的文件类型 (GIF)的主要内容,如果未能解决你的问题,请参考以下文章

从 PHAsset 获取视频时如何检测视频是不是为横向/纵向?

iOS:PHAsset 和检测 DNG RAW 格式

phasset 子类型 rawValue 意味着 swift

从 iOS 8 中的 PHAsset 获取文件扩展名?

如何检索 PHAsset 的元数据?

如何从 PHAsset 获取原始图像和媒体类型?