【问题标题】:Avoiding duplicates when getting pictures with PHAsset使用 PHAsset 获取图片时避免重复
【发布时间】:2014-11-11 01:02:13
【问题描述】:

在 iOS 8 上,我想获取设备上存储的所有图片。我的问题是我确实得到了它们,但有些不止一次出现。 PHAsset 属性(隐藏、mediaSubtypes 等)对于所有图片都是相同的,因此我不能排除 PHAssetMediaSubtypePhotoHDR 子类型。我发现的唯一方法是不添加具有相同日期的多张图片,但是当使用相同的创建日期保存多张照片时,这是一个问题。

有人知道我为什么会得到这些重复项以及我可以做些什么来避免它们吗?

这就是我获取图片的方式:

    PHFetchOptions *fetchOptions = [PHFetchOptions new];
    fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES],];
    PHFetchResult *phAssets = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];

【问题讨论】:

  • 重复的图片是指向同一张图片还是只是视觉上相同?
  • 它们指向视觉上相同的不同图片。它们的“creationDate”可以相同,也可以显示出微乎其微的差异。
  • 它们听起来像爆发。参照。在下面回答。

标签: ios objective-c ios8 photos


【解决方案1】:

我遇到了同样的问题,对我来说,重复的图像是我的照片流相册中的图像。为了解决这个问题,我现在使用 PHAssetCollection 类中的 FetchMoments 方法,然后在获取结果中获取每个时刻的所有资产。这样我就可以得到所有图像而不会得到重复的图像。

如果有人找到更好的解决方案,请告诉我。

【讨论】:

  • 非常感谢您的回答。你的和 Ponf 的似乎同时出现并且相似。我不得不选择他的答案并将其标记为答案,因为即使您的解释更好,他也包含了工作代码,这可能会让遇到同样问题的人更快地获得帮助。
  • 是的,这也是我一直在使用的。它运行良好,仍然可以拾取 iCloud 照片。
【解决方案2】:

您可以尝试使用朋友圈收藏:

PHFetchResult * moments = [PHAssetCollection fetchMomentsWithOptions:nil];            
for (PHAssetCollection * moment in moments) {
    PHFetchResult * assetsFetchResults = [PHAsset fetchAssetsInAssetCollection:moment options:nil];
    for (PHAsset * asset in assetsFetchResults) {
        //Do something with asset, for example add them to array
    }
}

【讨论】:

  • 上述方法的问题是您需要事先获取所有资产 - 这需要时间。在拥有数千张图像的 iPhone 5S 上,它花费了大约 1.5 秒。我们不能等那么久!
  • @TapanThaker - 它花时间在哪里?是只抓取 PHAsset 并将其放入数组中,还是您正在做其他事情?我很快也会关注这个问题。
  • 只是把它放在一个数组中。
  • 用户有数千张图片,大约 3-4 K
  • 这是我用来避免重复的方法。我有大约 5000 张照片和 250 个视频,但它在不到一秒的时间内完成了工作。您是在打印一堆东西还是在做一些浪费的事情?我遇到的问题是 PHAssetCollections 是不可变的,因此您必须使用 NSMutableArray 来代替,这在新照片通知中效果不佳。
【解决方案3】:

自 iOS 8.1 起,fetchAssetsWithMediaType:fetchAssetsWithOptions: 方法的行为发生了变化,它们不再包括从 iTunes 同步到设备的照片或存储在 iCloud 共享照片流中的照片。

来源:Document Revision HistoryPHAsset Class Reference

【讨论】:

  • 我很震惊——震惊!——发现两个 Apple 链接都已损坏。我正在积极研究这一点,并且真诚地希望看到此声明的文档或备份。
  • @ClayBridges:第二个链接指向 Apple 的 PHAsset 类参考。如果您展开 fetchAssetsWithMediaType:options: 方法文档,您可以阅读 讨论 部分中的以下注释:重要 - 如果此方法由在 iOS 8.1 或之后链接的应用程序调用,则结果不包括从 iTunes 同步到设备的照片或存储在 iCloud 共享照片流中的照片。
【解决方案4】:

在传单上,这些资产是爆破的一部分吗? (参见PHAsset.burstIdentifier等)如果是这样,您可以进行相应的调整。

【讨论】:

    【解决方案5】:

    例如,您可以使用“PHImageRequestOptions”来设置高质量的图像!

    //Setting up the deliveryMode in PHImageRequestOptions()
    fileprivate func imageRequestOptions() -> PHImageRequestOptions {
        let requestOption = PHImageRequestOptions()
        requestOption.deliveryMode = .highQualityFormat
        return requestOption
    }
    
    fileprivate func fetchImages(){
    
        let fetchOptions = assetsFetchOptions() //get fetchOptions only. Don`t worry
        let allPhotos = PHAsset.fetchAssets(with: .image, options: fetchOptions)
    
        allPhotos.enumerateObjects({ (asset, index, stop) in
            print(asset)
    
            let imageManager = PHImageManager.default()
            let targetSize = CGSize(width: 200, height: 200)
    
            //This function uses the "imageRequestOptions()" function to set up the "options:" field in this .requestImage() function.
            imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFit, options: self.imageRequestOptions(), resultHandler: { (image, info) in
    
                if let image = image {
                    self.images.append(image)
                    self.assets.append(asset)
    
                    if self.selectedImage == nil {
                        self.selectedImage = image
                    }
                }
    
                if index == allPhotos.count - 1 {
                    self.collectionView?.reloadData()
                }
            })
        })
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-08
      • 2019-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-07
      相关资源
      最近更新 更多