ios 从 Photos.app 获取最后一张图片?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8867496/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:19:13  来源:igfitidea点击:

Get last image from Photos.app?

iosimagecameraphotos

提问by SimplyKiwi

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?

我见过其他应用程序这样做,您可以从“照片”应用程序导入最后一张照片以便快速使用,但据我所知,我只知道如何获取图像而不是最后一张(最近的)。谁能告诉我如何获得最后一张图片?

回答by SimplyKiwi

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

此代码片段将从相机胶卷(iOS 7 及更低版本)中获取最新图像:

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:

iOS 8 及以上:

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];

                                           });
                                       }];

回答by Liam

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

iBrad 的出色回答,对我来说几乎完美无缺。唯一的例外是它以原始方向(例如颠倒、-90° 等)返回图像。

To fix this I simply changed fullResolutionImageto fullScreenImage.

为了解决这个问题,我只是改变了fullResolutionImagefullScreenImage

Here:

这里:

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

It now works a treat.

它现在是一种享受。

回答by isaac

iBrad's example includes an iOS8 snippet that apparently works, but I found myself confused by the return type he described. Here is a snippet that grabs the last image, including options for version and size requirements.

iBrad 的示例包含一个显然有效的 iOS8 代码段,但我发现自己对他描述的返回类型感到困惑。这是抓取最后一张图片的片段,包括版本和大小要求的选项。

Of note are the ability to request a specific version (original, current) and size. In my case, as I wish to apply the returned image to a button, I request it sized and scaled to fit the button I'm applying it to:

值得注意的是可以请求特定版本(原始版本、当前版本)和大小。就我而言,由于我希望将返回的图像应用于按钮,因此我请求调整其大小和缩放以适合我将其应用于的按钮:

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];

                                           });
                                       }];

回答by Javier Chávarri

Thanks for your answer iBrad Apps.

感谢您的回答 iBrad 应用程序。

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
    }

回答by Lonkly

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

好吧,这是一个如何使用Swift 3人从画廊加载最后一张图像的解决方案:

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 PHImageRequestOptionsand set those:

如果您需要更高的速度,您还可以使用PHImageRequestOptions和设置这些:

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

这是你在 viewController 中获取它的方式(你应该用你的类替换 GalleryManager.manager):

GalleryManager.manager.loadLastImageThumb { [weak self] (image) in
      DispatchQueue.main.async {
           self?.galleryButton.setImage(image, for: .normal)
      }
}

回答by jemeshsu

Refer to answer by Liam. fullScreenImagewill return a scaled image fitting your device's screen size. For getting the actual image size:

参考利亚姆的回答。fullScreenImage将返回适合您设备屏幕尺寸的缩放图像。获取实际图像大小:

  ALAssetRepresentation *representation = [alAsset defaultRepresentation];
  ALAssetOrientation orientation = [representation orientation];
  UIImage *latestPhoto = [UIImage imageWithCGImage:[representation fullResolutionImage] scale:[representation scale] orientation:(UIImageOrientation)orientation];                    

Quoting Apple's ALAssetRepresentation Class Reference on fullResolutionImage:

引用 Apple 的 ALAssetRepresentation 类参考fullResolutionImage

To create a correctly-rotated UIImage object from the CGImage, you use imageWithCGImage:scale:orientation: or initWithCGImage:scale:orientation:, passing the values of orientation and scale.

要从 CGImage 创建正确旋转的 UIImage 对象,请使用 imageWithCGImage:scale:orientation: 或 initWithCGImage:scale:orientation:,传递方向和比例的值。

回答by AaronG

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:

此行在以下之后缺少冒号indexSetWithIndex

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

回答by voidref

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

这是Swift中的一个版本,它请求数据并将其转换为 UIImage,因为提供的版本每次都返回一个空的 UIImage

    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

             }
        }
    }

回答by Steve N

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

基于 iBrad 的回答,这里有一个快速而肮脏的 Swift 版本,适用于 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.

注意:这需要 iOS 8.0+。请务必链接照片框架并在您的文件中添加“导入照片”。

回答by RyanG

Heres a combination of iBrad's & Javier's answers (which worked great), but I am getting the thumbnail asset instead of the full resolution image. Some others may find this handy.

这是 iBrad 和 Javier 的答案的组合(效果很好),但我得到的是缩略图资产而不是全分辨率图像。其他一些人可能会觉得这很方便。

- (void)setCameraRollImage {
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    [library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
        [group setAssetsFilter:[ALAssetsFilter allPhotos]];
        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) {
                    UIImage *latestPhoto = [UIImage imageWithCGImage:[alAsset thumbnail]];
                    [self.cameraRollButton setImage:latestPhoto forState:UIControlStateNormal];
                }
            }];
        }
    } failureBlock: ^(NSError *error) {
    }];
}