Comment obtenir seulement des images dans le rouleau de l'appareil photo en utilisant le cadre de Photos

le code suivant charge des images qui sont également localisées sur iCloud ou les images de flux. Comment peut-on limiter la recherche aux seules images sur la pellicule?

var assets = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: nil)
21
demandé sur William Falcon 2014-09-08 22:31:59

8 réponses

après avoir ajouté le rouleau de caméra et les albums de flux de photos, Apple a ajouté le PHAssetCollectionSubtype types d'iOS 8.1:

  1. PHAssetCollectionSubtypeAlbumMyPhotoStream (avec PHAssetCollectionTypeAlbum) - va chercher l'album Photo Stream.

  2. PHAssetCollectionSubtypeSmartAlbumUserLibrary (avec PHAssetCollectionTypeSmartAlbum) - extrait de l'album pellicule.

N'ont pas testé si c'est rétrocompatible avec iOS 8.0.x cependant.

19
répondu StatusReport 2015-01-21 09:22:59

a travers quelques expérimentations nous avons découvert une propriété cachée non listée dans la documentation (assetSource). Fondamentalement, vous devez faire une demande de fetch régulière, puis utiliser un prédicat pour filtrer ceux du rouleau de caméra. Cette valeur devrait être de 3.

exemple de code:

//fetch all assets, then sub fetch only the range we need
var assets = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: fetchOptions)

assets.enumerateObjectsUsingBlock { (obj, idx, bool) -> Void in
    results.addObject(obj)
}

var cameraRollAssets = results.filteredArrayUsingPredicate(NSPredicate(format: "assetSource == %@", argumentArray: [3]))
results = NSMutableArray(array: cameraRollAssets)
4
répondu William Falcon 2014-09-08 21:03:28

Si vous utilisez votre propre PHCachingImageManager au lieu du PHImageManager instance alors quand vous appelez requestImageForAsset:targetSize:contentMode:options:resultHandler: vous pouvez définir une option dans PHImageRequestOptions pour spécifier que l'image est locale.

networkaccess allowed La propriété

une valeur booléenne qui spécifie si les Photos peuvent télécharger l'image demandée à partir d'iCloud.

networkaccess allowed

Discussion

si oui, et le l'image demandée n'est pas stockée sur le périphérique local, les photos téléchargent l'image à partir d'iCloud. Pour être informé de la progression du téléchargement, utilisez la propriété progressHandler pour fournir un bloc que Photos appelle périodiquement lors du téléchargement de l'image. Si non (par défaut), et que l'image n'est pas sur le périphérique local, la valeur PHImageResultIsInCloudKey dans le dictionnaire d'information du gestionnaire indique que l'image n'est pas disponible à moins que vous n'activiez l'accès au réseau.

3
répondu Grimxn 2016-04-30 12:08:47

si vous cherchez comme moi le code de L'Objectif C, et aussi que vous n'avez pas obtenu la réponse de la nouvelle bibliothèque / cadre de Photo comme vous obteniez le code d'AssetsLibrary déprécié, alors cela vous aidera: Swift

Variables Globales:

var imageArray: [AnyObject]
var mutableArray: [AnyObject]

convenience func getAllPhotosFromCamera() {
    imageArray = [AnyObject]()
    mutableArray = [AnyObject]()
    var requestOptions: PHImageRequestOptions = PHImageRequestOptions()
    requestOptions.resizeMode = .Exact
    requestOptions.deliveryMode = .HighQualityFormat
    requestOptions.synchronous = true
    var result: PHFetchResult = PHAsset.fetchAssetsWithMediaType(.Image, options: nil)
    NSLog("%d", Int(result.count))
    var manager: PHImageManager = PHImageManager.defaultManager()
    var images: [AnyObject] = [AnyObject](minimumCapacity: result.count)
        // assets contains PHAsset objects.
    var ima: UIImage
    for asset: PHAsset in result {
        // Do something with the asset
        manager.requestImageForAsset(asset, targetSize: PHImageManagerMaximumSize, contentMode: .Default, options: requestOptions, resultHandler: {(image: UIImage, info: [NSObject : AnyObject]) -> void in

Objectif C

Variables Globales:

NSArray *imageArray;
NSMutableArray *mutableArray;

méthode ci-dessous vous aidera à:

-(void)getAllPhotosFromCamera
{
    imageArray=[[NSArray alloc] init];
    mutableArray =[[NSMutableArray alloc]init];

    PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
    requestOptions.resizeMode   = PHImageRequestOptionsResizeModeExact;
    requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
    requestOptions.synchronous = true;
    PHFetchResult *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];

    NSLog(@"%d",(int)result.count);

    PHImageManager *manager = [PHImageManager defaultManager];
    NSMutableArray *images = [NSMutableArray arrayWithCapacity:[result count]];

    // assets contains PHAsset objects.

    __block UIImage *ima;
    for (PHAsset *asset in result) {
        // Do something with the asset

        [manager requestImageForAsset:asset
                           targetSize:PHImageManagerMaximumSize
                          contentMode:PHImageContentModeDefault
                              options:requestOptions
                        resultHandler:^void(UIImage *image, NSDictionary *info) {
                            ima = image;

                            [images addObject:ima];
                        }];


    }

    imageArray = [images copy];  // You can direct use NSMutuable Array images
}
3
répondu karan 2016-06-28 11:46:49

ceci peut aider. Vous pouvez utiliser votre propre modèle de données à la place D'AlbumModel que j'ai utilisé.

func getCameraRoll() -> AlbumModel {
          var cameraRollAlbum : AlbumModel!

          let cameraRoll = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: nil)

          cameraRoll.enumerateObjects({ (object: AnyObject!, count: Int, stop: UnsafeMutablePointer) in
            if object is PHAssetCollection {
              let obj:PHAssetCollection = object as! PHAssetCollection

              let fetchOptions = PHFetchOptions()
              fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
              fetchOptions.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue)
              let assets = PHAsset.fetchAssets(in: obj, options: fetchOptions)

              if assets.count > 0 {
                let newAlbum = AlbumModel(name: obj.localizedTitle!, count: assets.count, collection:obj, assets: assets)

                cameraRollAlbum = newAlbum
              }
            }
          })
         return cameraRollAlbum

        }
1
répondu jamesthakid 2017-10-10 15:04:24

Voici la version Objective - c fournie par apple.

-(NSMutableArray *)getNumberOfPhotoFromCameraRoll:(NSArray *)array{
    PHFetchResult *fetchResult = array[1];
    int index = 0;
    unsigned long pictures = 0;
    for(int i = 0; i < fetchResult.count; i++){
        unsigned long temp = 0;
        temp = [PHAsset fetchAssetsInAssetCollection:fetchResult[i] options:nil].count;
        if(temp > pictures ){
            pictures = temp;
            index = i;
        }
    }
    PHCollection *collection = fetchResult[index];

       if (![collection isKindOfClass:[PHAssetCollection class]]) {
        // return;
    }
    // Configure the AAPLAssetGridViewController with the asset collection.
    PHAssetCollection *assetCollection = (PHAssetCollection *)collection;
    PHFetchResult *assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];
    self. assetsFetchResults = assetsFetchResult;
    self. assetCollection = assetCollection;
    self.numberOfPhotoArray = [NSMutableArray array];
    for (int i = 0; i<[assetsFetchResult count]; i++) {
        PHAsset *asset = assetsFetchResult[i];
        [self.numberOfPhotoArray addObject:asset];
    }
    NSLog(@"%lu",(unsigned long)[self.numberOfPhotoArray count]);
    return self.numberOfPhotoArray;
}

Où vous pouvez saisir détails suivants

PHFetchResult *fetchResult = self.sectionFetchResults[1];
        PHCollection *collection = fetchResult[6];
**value 1,6 used to get camera images**
**value 1,0 used to get screen shots**
**value 1,1 used to get hidden**
**value 1,2 used to get selfies** 
**value 1,3 used to get recently added**
**value 1,4 used to get videos**
**value 1,5 used to get recently deleted**
 **value 1,7 used to get favorites**

Apple demo lien

Déclarez votre propriété

@property (nonatomic, strong) NSArray *sectionFetchResults;
@property (nonatomic, strong) PHFetchResult *assetsFetchResults;
@property (nonatomic, strong) PHAssetCollection *assetCollection;
@property (nonatomic, strong) NSMutableArray *numberOfPhotoArray;
0
répondu karthikeyan 2016-07-31 08:04:20

je me suis cogné la tête à cause de ça aussi. Je n'ai trouvé aucun moyen de filtrer pour seulement les actifs sur l'appareil avec fetchAssetsWithMediaType ou fetchAssetsInAssetCollection. Je suis en mesure d'utiliser requestContentEditingInputWithOptions ou requestigedataforasset pour déterminer si l'actif est sur l'appareil ou non, mais c'est asynchrone et semble utiliser beaucoup trop de ressources à faire pour chaque actif de la liste. Il doit y avoir une meilleure façon.

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

for (int i=0; i<[fetchResult count]; i++) {

    PHAsset *asset = fetchResult[i];

    [asset requestContentEditingInputWithOptions:nil
                               completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
                                   if ([[info objectForKey:PHContentEditingInputResultIsInCloudKey] intValue] == 1) {
                                       NSLog(@"asset is in cloud");
                                   } else {
                                       NSLog(@"asset is on device");
                                   }
                               }];

}
0
répondu Tom Kincaid 2017-07-28 14:10:04

si vous ne voulez pas vous fier à une API non documentée, regardez [asset canPerformEditOperation:PHAssetEditOperationContent]. Ceci ne retourne true que si l'original complet est disponible sur l'appareil.

certes, c'est aussi fragile, mais les tests montrent que cela fonctionne pour tous les types d'assetSource (photostream, iTunes sync, etc.).

-1
répondu delrox 2014-09-29 21:31:00