Подтвердить что ты не робот

Как получить только изображения в кадре камеры с помощью Photos Framework

Следующий код загружает изображения, которые также расположены на изображениях iCloud или в потоках. Как мы можем ограничить поиск только изображениями в кадре камеры?

var assets = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: nil)
4b9b3361

Ответ 1

В ходе некоторых экспериментов мы обнаружили скрытое свойство, не указанное в документации (assetSource). В основном вам нужно выполнить регулярный запрос на выборку, а затем использовать предикат для фильтрации их из рулона камеры. Это значение должно быть 3.

Пример кода:

//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)

Ответ 2

После добавления альбомов Camera Roll и Photo Stream Apple добавила следующие типы PHAssetCollectionSubtype в iOS 8.1:

  • PHAssetCollectionSubtypeAlbumMyPhotoStream (вместе с PHAssetCollectionTypeAlbum) - выбирает альбом Photo Stream.

  • PHAssetCollectionSubtypeSmartAlbumUserLibrary (вместе с PHAssetCollectionTypeSmartAlbum) - выбирает альбом Camera Roll.

Не проверял, совместимо ли это с iOS 8.0.x.

Ответ 3

Если вы ищете, как я для Objective C, а также вы не получили ответ на новую библиотеку /Photo Framework, поскольку вы получали устаревший код AssetsLibrary, тогда это поможет вам: Swift

Глобальные переменные:

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

Цель C

Глобальные переменные:

NSArray *imageArray;
NSMutableArray *mutableArray;

ниже метод поможет вам:

-(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
}

Ответ 4

Если вы используете собственный PHCachingImageManager вместо общего экземпляра PHImageManager, то при вызове requestImageForAsset:targetSize:contentMode:options:resultHandler: вы можете установить опцию в PHImageRequestOptions, чтобы указать, что изображение является локальным.

networkAccessAllowed Свойство

Логическое значение, указывающее, может ли Photos загружать запрошенное изображение из iCloud.

networkAccessAllowed

Обсуждение

Если ДА, а запрошенное изображение не сохраняется на локальном устройстве, фотографии загружают изображение из iCloud. Чтобы получить уведомление о ходе загрузки, используйте свойство progressHandler, чтобы предоставить блок, который периодически вызывает фотографии при загрузке изображения. Если NO (по умолчанию), а изображение отсутствует на локальном устройстве, значение PHImageResultIsInCloudKey в словаре информации о обработчиках результатов указывает, что изображение недоступно, если вы не разрешаете доступ к сети.

Ответ 5

Это может помочь. Вы можете использовать свою собственную модель данных вместо используемого мной AlbumModel.

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

        }

Ответ 6

Вот версия Objective-c, предоставленная 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;
}

Где вы можете получить следующие данные

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 ссылка

Объявите свое свойство

@property (nonatomic, strong) NSArray *sectionFetchResults;
@property (nonatomic, strong) PHFetchResult *assetsFetchResults;
@property (nonatomic, strong) PHAssetCollection *assetCollection;
@property (nonatomic, strong) NSMutableArray *numberOfPhotoArray;

Ответ 7

Я тоже ударился головой об этом. Я не нашел способа фильтровать только активы на устройстве с помощью fetchAssetsWithMediaType или fetchAssetsInAssetCollection. Я могу использовать requestContentEditingInputWithOptions или requestImageDataForAsset, чтобы определить, находится ли объект на устройстве или нет, но это асинхронно и похоже на него, используя слишком много ресурсов для каждого актива в списке. Должен быть лучший способ.

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");
                                   }
                               }];

}

Ответ 8

Если вы не хотите полагаться на недокументированный API, посмотрите [asset canPerformEditOperation:PHAssetEditOperationContent]. Это возвращает true только в том случае, если на устройстве имеется полный оригинал.

По общему признанию, это также является хрупким, но тестирование показывает, что он работает для всех типов источников активов (фотопоток, синхронизация iTunes и т.д.).