Get last image from Photos.app?

后端 未结 13 2042
萌比男神i
萌比男神i 2020-11-27 09:50

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

相关标签:
13条回答
  • 2020-11-27 10:06

    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)
          }
    }
    
    0 讨论(0)
  • 2020-11-27 10:08

    Great answer from iBrad, worked almost perfectly for me. The exception being that it was returning images at their original orientation (eg. upside down, -90°, etc).

    To fix this I simply changed fullResolutionImage to fullScreenImage.

    Here:

    UIImage *latestPhoto = [UIImage imageWithCGImage:[representation fullScreenImage]];
    

    It now works a treat.

    0 讨论(0)
  • 2020-11-27 10:08

    Here is a version in Swift which requests the data and converts it to an UIImage, as the provided version returned an empty UIImage every time

        let fetchOptions = PHFetchOptions()
        fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
    
        let fetchResult = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: fetchOptions)
    
        if let lastAsset: PHAsset = fetchResult.lastObject as? PHAsset {
            let manager = PHImageManager.defaultManager()
            let imageRequestOptions = PHImageRequestOptions()
    
            manager.requestImageDataForAsset(lastAsset, options: imageRequestOptions) {
                (let imageData: NSData?, let dataUTI: String?,
                 let orientation: UIImageOrientation,
                 let info: [NSObject : AnyObject]?) -> Void in
    
                 if let imageDataUnwrapped = imageData, lastImageRetrieved = UIImage(data: imageDataUnwrapped) {
                    // do stuff with image
    
                 }
            }
        }
    
    0 讨论(0)
  • 2020-11-27 10:10

    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
        }
    
    0 讨论(0)
  • 2020-11-27 10:16

    I found a typo that I'm embarrassed to admit to me longer than it should have to figure out. Maybe it will save someone else some time.

    This line was missing a colon after indexSetWithIndex:

    [group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:[group numberOfAssets] - 1]options:0 usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {
    
    0 讨论(0)
  • 2020-11-27 10:16

    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);
                });
        }
    
    0 讨论(0)
提交回复
热议问题