Get last image from Photos.app?

2019-01-05 07:59发布

I have seen other apps do it where you can import the last photo from the Photos app for quick use but as far as I know, I only know how to get A image and not the last (most recent one). Can anyone show me how to get the last image?

13条回答
【Aperson】
2楼-- · 2019-01-05 08:13

Building upon iBrad's answer, here's a quick & dirty Swift version that works for me in iOS 8.1:

let imgManager = PHImageManager.defaultManager()
var fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending: true)]
if let fetchResult = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: fetchOptions) {
    imgManager.requestImageForAsset(fetchResult.lastObject as PHAsset, targetSize: self.destinationImageView.frame.size, contentMode: PHImageContentMode.AspectFill, options: nil, resultHandler: { (image, _) in
        self.destinationImageView.image = image
    })
}

Note: this requires iOS 8.0+. Be sure to link the Photos framework and add "import Photos" in your file.

查看更多
The star\"
3楼-- · 2019-01-05 08:13

The following code works with iOS7 and iOS8. It also checks if there is an image in the filter. Before you execute the code you should check the album permission:

// get the latest image from the album
-(void)getLatestPhoto
{
    NSLog(@"MMM TGCameraViewController - getLatestPhoto");
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

    // Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.
    [library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {

        // Within the group enumeration block, filter to enumerate just photos.
        [group setAssetsFilter:[ALAssetsFilter allPhotos]];

        // For this example, we're only interested in the last item [group numberOfAssets]-1 = last.
        if ([group numberOfAssets] > 0) {

            [group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:[group numberOfAssets]-1]
                                    options:0
                                 usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {

                                     // The end of the enumeration is signaled by asset == nil.
                                     if (alAsset) {
                                         ALAssetRepresentation *representation = [alAsset defaultRepresentation];
                                         // Do something interesting with the AV asset.
                                         UIImage *img = [UIImage imageWithCGImage:[representation fullScreenImage]];

                                         // use the photo here ...


                                         // we only need the first (most recent) photo -- stop the enumeration
                                         *innerStop = YES;
                                     }
                                 }];
        }
    }
    failureBlock: ^(NSError *error) {
       // Typically you should handle an error more gracefully than this.
       NSLog(@"No groups");
    }];
}  

(This code is a modified version from here.)

查看更多
家丑人穷心不美
4楼-- · 2019-01-05 08:14

Thanks for your answer iBrad Apps.

Just wanted to point out an error prevention for the special case when user has no images on his/her photo roll (strange case I know):

    // Within the group enumeration block, filter to enumerate just photos.
    [group setAssetsFilter:[ALAssetsFilter allPhotos]];

    //Check that the group has more than one picture
    if ([group numberOfAssets] > 0) {
        // Chooses the photo at the last index
        [group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:([group numberOfAssets] - 1)] options:0 usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {

            // The end of the enumeration is signaled by asset == nil.
            if (alAsset) {
                ALAssetRepresentation *representation = [alAsset defaultRepresentation];
                UIImage *latestPhoto = [UIImage imageWithCGImage:[representation fullScreenImage]];

                [self.libraryButton setImage:latestPhoto forState:UIControlStateNormal];
            }
        }];
    }
    else {
      //Handle this special case
    }
查看更多
Ridiculous、
5楼-- · 2019-01-05 08:16

Well, here is a solution of how to load last image from gallery with Swift 3 guys:

func loadLastImageThumb(completion: @escaping (UIImage) -> ()) {
    let imgManager = PHImageManager.default()
    let fetchOptions = PHFetchOptions()
    fetchOptions.fetchLimit = 1
    fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending: true)]

    let fetchResult = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: fetchOptions)

    if let last = fetchResult.lastObject {
        let scale = UIScreen.main.scale
        let size = CGSize(width: 100 * scale, height: 100 * scale)
        let options = PHImageRequestOptions()


        imgManager.requestImage(for: last, targetSize: size, contentMode: PHImageContentMode.aspectFill, options: options, resultHandler: { (image, _) in
            if let image = image {
                completion(image)
            }
        })
    }

}

If you need more speed, you can also use PHImageRequestOptions and set those:

options.deliveryMode = .fastFormat
options.resizeMode = .fast

And this is the way you get it in your viewController (you should replace GalleryManager.manager with your class):

GalleryManager.manager.loadLastImageThumb { [weak self] (image) in
      DispatchQueue.main.async {
           self?.galleryButton.setImage(image, for: .normal)
      }
}
查看更多
We Are One
6楼-- · 2019-01-05 08:19

Xamarin.iOS version of accepted answer (how to get last image) including all notices from other answers:

  private void ChooseLastTakenPictureImplementation()
    {
        var library = new ALAssetsLibrary();
        // Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.
        library.Enumerate(ALAssetsGroupType.SavedPhotos, (ALAssetsGroup assetsGroup, ref bool stop) =>
            {
                if (stop || assetsGroup == null)
                {
                    return;
                }
                //Xamarin does not support ref parameters in nested lamba expressions
                var lambdaStop = false;
                //Check that the group has more than one picture
                if (assetsGroup.Count > 0)
                {
                    // Within the group enumeration block, filter to enumerate just photos.
                    assetsGroup.SetAssetsFilter(ALAssetsFilter.AllPhotos);
                    // Chooses the photo at the last index
                    assetsGroup.Enumerate(NSEnumerationOptions.Reverse, (ALAsset result, int index, ref bool innerStop) =>
                        {
                            // The end of the enumeration is signaled by asset == nil.
                            if (result != null)
                            {
                                var representation = result.DefaultRepresentation;
                                var latestPhoto = new UIImage(representation.GetImage(), representation.Scale, (UIImageOrientation)representation.Orientation);
                                // Stop the enumerations
                                lambdaStop = innerStop = true;
                                // Do something interesting with the AV asset.
                                HandleImageAutoPick(latestPhoto);
                            }
                        });
                    stop = lambdaStop;
                    return;
                }
                else
                {
                    //Handle this special case where user has no pictures
                }
            }, error =>
            {
                // Typically you should handle an error more gracefully than this.
                Debug.WriteLine(error.Description);
            });
    }
查看更多
对你真心纯属浪费
7楼-- · 2019-01-05 08:24

This code snippet will get the latest image from the camera roll (iOS 7 and below):

ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

// Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {

    // Within the group enumeration block, filter to enumerate just photos.
    [group setAssetsFilter:[ALAssetsFilter allPhotos]];

    // Chooses the photo at the last index
    [group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {

        // The end of the enumeration is signaled by asset == nil.
        if (alAsset) {
            ALAssetRepresentation *representation = [alAsset defaultRepresentation];
            UIImage *latestPhoto = [UIImage imageWithCGImage:[representation fullScreenImage]];

            // Stop the enumerations
            *stop = YES; *innerStop = YES;

            // Do something interesting with the AV asset.
            [self sendTweet:latestPhoto];
        }
    }];
} failureBlock: ^(NSError *error) {
    // Typically you should handle an error more gracefully than this.
    NSLog(@"No groups");
}];

iOS 8 and above:

PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
PHAsset *lastAsset = [fetchResult lastObject];
[[PHImageManager defaultManager] requestImageForAsset:lastAsset
                                          targetSize:self.photoLibraryButton.bounds.size
                                         contentMode:PHImageContentModeAspectFill
                                             options:PHImageRequestOptionsVersionCurrent
                                       resultHandler:^(UIImage *result, NSDictionary *info) {

                                           dispatch_async(dispatch_get_main_queue(), ^{

                                               [[self photoLibraryButton] setImage:result forState:UIControlStateNormal];

                                           });
                                       }];
查看更多
登录 后发表回答