3

I got Apple's sample code for 'SamplePhotosApp' and in the photo album grid photo layout, trying to detect DNG RAW files (put up a badge if it's DNG).

Default cellForItemAt:

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let asset = fetchResult.object(at: indexPath.item)

        // Dequeue a GridViewCell.
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: GridViewCell.self), for: indexPath) as? GridViewCell
            else { fatalError("unexpected cell in collection view") }

        // Add a badge to the cell if the PHAsset represents a Live Photo.
        if asset.mediaSubtypes.contains(.photoLive) {
            cell.livePhotoBadgeImage = PHLivePhotoView.livePhotoBadgeImage(options: .overContent)
        }

        // Request an image for the asset from the PHCachingImageManager.
        cell.representedAssetIdentifier = asset.localIdentifier
        imageManager.requestImage(for: asset, targetSize: thumbnailSize, 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.
            if cell.representedAssetIdentifier == asset.localIdentifier {
                cell.thumbnailImage = image
            }
        })

        return cell

    }

DNG/RAW Format

With DNG files, there could be a preview or thumbnail (with iOS11) embedded in it, and of course a completely separate JPEG attached to it.

With above code, requestImage still displays DNG files by pulling out its embedded JPEG. However, it doesn't know that the PHAsset is actually a DNG file.

How can I find out if the PHAsset is a DNG?


Things I Tried

let fileExtension = ((asset.value(forKey: "uniformTypeIdentifier") as! NSString).pathExtension as NSString).uppercased
if fileExtension == "DNG" || fileExtension == "RAW-IMAGE" {
     //Show RAW Badge
}

Above works only if the DNG file has just the preview JPEG embedded. If it has a regular full-size JPEG embedded, it recognize the PHAsset as a JPEG.

I've been told to try this:

let res = PHAssetResource.assetResources(for: asset)

But a certain asset could have several number of resources (adjustment data, etc). How would I be able to make this work?

4

1 回答 1

11

一些概念背景:在 PhotoKit 中可以处理三个级别......

  • 当您与PHAsset朋友一起工作时,您处于抽象模型级别。每个资产都是照片数据库中的一个条目——在照片应用程序中显示为缩略图的单个“事物”。在这一层,它只是一个“东西”(不是像素缓冲区或视频数据流)。

  • 当您使用 时PHImageManager,您仍然是在抽象地工作。您是在告诉 PhotoKit,“给我一张图片(或视频),这是在这些情况下向用户展示此资产的合适方式。” 什么样的文件包含资产的原始数据仍然在这个级别被抽象掉。

  • 这些抽象“事物”中的每一个都可能有一个或多个原始文件,提供其图像或视频数据、内在元数据等。要处理这些问题(包括文件格式),您需要PHAssetResource(并且可能PHAssetResourceManager)处理这些问题。

因此,如果您要查明资产是否包含 RAW 或 DNG 数据,则需要查看其资源。

  1. 用于获取资产对应的资源集。PHAssetResource.assetResources(for:)

  2. 通过检查每个资源的属性来缩小资源列表type- 由 RAW 或 DNG 文件支持的资产应将其存储在该alternatePhoto类型的资源中。(尽管第三方应用程序至少有可能使用该fullSizePhoto类型编写 DNG 文件,因此您也可以在那里检查。)

  3. 检查uniformTypeIdentifier缩小列表中每个资源的属性。DNG 文件的 UTI 是"com.adobe.raw-image"(在 Xcode 9 中有一个字符串常量,AVFileTypeDNG)。如果您只想要 DNG 文件,那可能很好,但要更广泛地检查 RAW 文件,最好测试资源的 UTI 是否符合"public.camera-raw-image"akakUTTypeRawImage .

于 2017-09-25T21:45:44.833 回答