从Photos.app获取最新图片?

Sim*_*iwi 53 camera image photos ios

我已经看到其他应用程序可以从照片应用程序中导入最后一张照片以便快速使用,但据我所知,我只知道如何获取A图像而不是最后一张(最近的图像).谁能告诉我如何获取最后一张图片?

Sim*_*iwi 106

此代码段将从相机胶卷(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");
}];
Run Code Online (Sandbox Code Playgroud)

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

                                           });
                                       }];
Run Code Online (Sandbox Code Playgroud)

  • 注意:如果相机胶卷中没有照片,此代码将崩溃.在现实世界中不常见,但仍然需要检查.我添加了`if([group numberOfAssets] <1)返回;`在第一个块级别内进行防御. (11认同)
  • 哦 - 嗯 - iOS 8代码已经过测试?我不认为PHFetchResult.lastObject返回一个UIImage? (3认同)
  • @iBradApps`enumerateAssetsAtIndexes:options:usingBlock:`替换为`enumerateAssetsWithOptions:usingBlock:`和选项`NSEnumerationReverse`.通过添加使用`stop`和`innerStop`布尔变量,我们仍然会在找到资产后停止枚举.您可以在http://stackoverflow.com/posts/8872425/revisions上查看差异 (2认同)
  • PHAsset对象没有图像数据,它只是图像的"元数据"! (2认同)
  • fetchResult.lastObject为你返回一个图像是很奇怪的.文档建议它应该返回一个PHAsset,然后应该用它来获取图像并支持各种选项(大小,版本等).我不知道这对你来说是如何为我和一个PHAsset返回一个UIImage.我已经为感兴趣的各方添加了一个包含PHAsset方法的答案(@ an0) (2认同)

Lia*_*iam 20

iBrad的答案很棒,对我来说几乎是完美的.唯一的例外是它以原始方向返回图像(例如,倒置,-90°等).

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

这里:

UIImage *latestPhoto = [UIImage imageWithCGImage:[representation fullScreenImage]];
Run Code Online (Sandbox Code Playgroud)

它现在有效.

  • 如果您只是显示图像,但实际上并没有获得完整分辨率图像,只有适合在用户设备上显示的图像,这种方法就有效.如果你需要一个完整大小的图像,你想要使用`UIImage*latestPhoto = [UIImage imageWithCGImage:[representation fullResolutionImage] scale:[表示比例]方向:[表示方向]]; (4认同)
  • 感谢您的建议,我对您的答案进行了投票,并将其纳入我的答案中!:) (2认同)

isa*_*aac 10

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

值得注意的是能够请求特定版本(原始,当前)和大小.在我的情况下,因为我希望将返回的图像应用于按钮,我请求它的大小和缩放以适合我正在应用它的按钮:

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

                                           });
                                       }];
Run Code Online (Sandbox Code Playgroud)

  • 这是iOS8 +的正确答案. (4认同)

Jav*_*rri 8

感谢您对iBrad Apps的回答.

只是想指出当用户在他/她的照片卷上没有图像时的特殊情况的错误预防(我知道奇怪的情况):

    // 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
    }
Run Code Online (Sandbox Code Playgroud)


Lon*_*kly 7

好吧,这是一个解决方案,如何从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)
            }
        })
    }

}
Run Code Online (Sandbox Code Playgroud)

如果你需要更快的速度,你也可以使用PHImageRequestOptions和设置:

options.deliveryMode = .fastFormat
options.resizeMode = .fast
Run Code Online (Sandbox Code Playgroud)

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

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


jem*_*hsu 5

请参阅利亚姆的回答.fullScreenImage将返回适合您设备屏幕尺寸的缩放图像.要获得实际图像大小:

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

引用Apple的ALAssetRepresentation类参考fullResolutionImage:

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