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

Как получить самую последнюю фотографию из Camera Roll на iOS?

Мне сложно понять, как программно извлекать самую последнюю фотографию в рулоне камеры без вмешательства пользователя. Чтобы быть ясным, я не хочу использовать Image Picker, я хочу, чтобы приложение автоматически захватывало самую новую фотографию при открытии приложения.

Я знаю, что это возможно, потому что я видел подобное приложение, но я не могу найти информацию об этом.

4b9b3361

Ответ 1

Один из способов - использовать AssetsLibrary и использовать n - 1 в качестве индекса для перечисления.

ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
[assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
                             usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
                                 if (nil != group) {
                                     // be sure to filter the group so you only get photos
                                     [group setAssetsFilter:[ALAssetsFilter allPhotos]];

                                     if (group.numberOfAssets > 0) {
                                         [group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:group.numberOfAssets - 1]
                                                                 options:0
                                                              usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
                                                                  if (nil != result) {
                                                                      ALAssetRepresentation *repr = [result defaultRepresentation];
                                                                      // this is the most recent saved photo
                                                                      UIImage *img = [UIImage imageWithCGImage:[repr fullResolutionImage]];
                                                                      // we only need the first (most recent) photo -- stop the enumeration
                                                                      *stop = YES;
                                                                  }
                                                              }];
                                     }
                                 }

                                 *stop = NO;
                             } failureBlock:^(NSError *error) {
                                 NSLog(@"error: %@", error);
                             }];

Ответ 2

Вместо того, чтобы возиться с индексом, вы можете перечислить список в обратном порядке. Этот шаблон работает хорошо, если вы хотите получить последнее изображение или хотите сначала отобразить изображения в UICollectionView с самым последним изображением.

Пример возврата последнего изображения:

[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop) {
    if (asset) {
        ALAssetRepresentation *repr = [asset defaultRepresentation];
        UIImage *img = [UIImage imageWithCGImage:[repr fullResolutionImage]];
        *stop = YES;
    }
}];

Ответ 3

В iOS 8 Apple добавила библиотеку Фотографии, которая упрощает запросы. В iOS 9 ALAssetLibrary устарел.

Здесь некоторый код Swift, чтобы получить самую последнюю фотографию с этой картой.

import UIKit
import Photos

struct LastPhotoRetriever {
    func queryLastPhoto(resizeTo size: CGSize?, queryCallback: (UIImage? -> Void)) {
        let fetchOptions = PHFetchOptions()
        fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]

//        fetchOptions.fetchLimit = 1 // This is available in iOS 9.

        if let fetchResult = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: fetchOptions) {
            if let asset = fetchResult.firstObject as? PHAsset {
                let manager = PHImageManager.defaultManager()

                // If you already know how you want to resize, 
                // great, otherwise, use full-size.
                let targetSize = size == nil ? CGSize(width: asset.pixelWidth, height: asset.pixelHeight) : size!

                // I arbitrarily chose AspectFit here. AspectFill is 
                // also available.
                manager.requestImageForAsset(asset,
                    targetSize: targetSize,
                    contentMode: .AspectFit,
                    options: nil,
                    resultHandler: { image, info in

                    queryCallback(image)
                })
            }
        }
    }
}

Ответ 4

Чтобы добавить к ответу Art Gillespie, используя fullResolutionImage, используйте исходное изображение, которое - в зависимости от ориентации устройства при съемке - может оставить вас с ног на голову или изображение -90 °.

Чтобы получить измененное, но оптимизированное изображение для этого, используйте fullScreenImage вместо этого.

 UIImage *img = [UIImage imageWithCGImage:[repr fullScreenImage]];

Ответ 5

Swift 3.0:

1) Импортируйте фреймворки в свой заголовок перед объявлением класса.

import Photos


2) Добавьте следующий метод, который возвращает последнее изображение.

func queryLastPhoto(resizeTo size: CGSize?, queryCallback: @escaping ((UIImage?) -> Void)) {
    let fetchOptions = PHFetchOptions()
    fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]

    let requestOptions = PHImageRequestOptions()
    requestOptions.isSynchronous = true

    let fetchResult = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: fetchOptions)
    if let asset = fetchResult.firstObject {
        let manager = PHImageManager.default()

        let targetSize = size == nil ? CGSize(width: asset.pixelWidth, height: asset.pixelHeight) : size!

        manager.requestImage(for: asset,
                             targetSize: targetSize,
                             contentMode: .aspectFit,
                             options: requestOptions,
                             resultHandler: { image, info in
                                queryCallback(image)
        })
    }

}


3) Затем вызовите этот метод где-нибудь в своем приложении (возможно, действие кнопки):

@IBAction func pressedLastPictureAttachmentButton(_ sender: Any) {
    queryLastPhoto(resizeTo: nil){
        image in
        print(image)
    }
}

Ответ 6

Ответ на вопрос (в Swift):

    func pickingTheLastImageFromThePhotoLibrary() {
        let assetsLibrary: ALAssetsLibrary = ALAssetsLibrary()
        assetsLibrary.enumerateGroupsWithTypes(ALAssetsGroupSavedPhotos,
            usingBlock: { (let group: ALAssetsGroup!, var stop: UnsafeMutablePointer<ObjCBool>) -> Void in
                if (group != nil) {
                    // Be sure to filter the group so you only get photos
                    group.setAssetsFilter(ALAssetsFilter.allPhotos())

                    group.enumerateAssetsWithOptions(NSEnumerationOptions.Reverse, 
                                 usingBlock: { (let asset: ALAsset!, 
                                                let index: Int, 
                                       var stop: UnsafeMutablePointer<ObjCBool>)
                                       -> Void in
                      if(asset != nil) {
                        /* 
                            Returns a CGImage representation of the asset.
                            Using the fullResolutionImage uses the original image which — depending on the
                            device orientation when taking the photo — could leave you with an upside down,
                            or -90° image. To get the modified, but optimised image for this, use
                            fullScreenImage instead.
                        */
                        // let myCGImage: CGImage! = asset.defaultRepresentation().fullResolutionImage().takeUnretainedValue()

                        /*
                            Returns a CGImage of the representation that is appropriate for displaying full
                            screen.
                        */
                        // let myCGImage: CGImage! = asset.defaultRepresentation().fullScreenImage().takeUnretainedValue()

                        /* Returns a thumbnail representation of the asset. */
                        let myCGImage: CGImage! = asset.thumbnail().takeUnretainedValue()

                        // Here we set the image included in the UIImageView
                        self.myUIImageView.image = UIImage(CGImage: myCGImage)

                        stop.memory = ObjCBool(true)
                      }
                    })
                }

                stop.memory = ObjCBool(false)
            })
            { (let error: NSError!) -> Void in
                 println("A problem occurred: \(error.localizedDescription)")
            }
    }

Ответ 7

Использование библиотеки фотографий (Objective-C)

    PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];

PHFetchResult *assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:fetchOptions];
if (assetsFetchResult.count>0) {
    PHAsset *asset = [assetsFetchResult objectAtIndex:0];

    CGFloat scale = [UIScreen mainScreen].scale;
    CGFloat dimension = 55.0f; // set your required size
    CGSize size = CGSizeMake(dimension*scale, dimension*scale);

    [[PHImageManager defaultManager] requestImageForAsset:asset
                                               targetSize:size
                                              contentMode:PHImageContentModeAspectFit
                                                  options:nil
                                            resultHandler:^(UIImage *result, NSDictionary *info) {
                                                // do your thing with the image
                                            }
     ];
}