我正在努力弄清楚如何在没有用户干预的情况下以编程方式检索相机胶卷中的最新照片。要清楚,我不想使用图像选择器,我希望应用程序在应用程序打开时自动抓取最新的照片。
我知道这是可能的,因为我见过类似的应用程序,但我似乎无法找到任何信息。
答案 0 :(得分:46)
一种方法是使用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);
}];
答案 1 :(得分:24)
您可以反过来列举列表,而不是弄乱索引。如果您想要最新的图像,或者如果您想要首先使用最新图像在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;
}
}];
答案 2 :(得分:11)
在iOS 8中,Apple添加了Photos library,这使得查询更容易。在iOS 9中,ALAssetLibrary
为deprecated。
这是一些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)
})
}
}
}
}
答案 3 :(得分:7)
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)
}
}
答案 4 :(得分:6)
要添加到艺术Gillespie的答案,使用fullResolutionImage
使用原始图像 - 根据拍摄照片时设备的方向 - 可能会让您倒置或-90°图像。
要为此获取已修改但优化的图像,请使用fullScreenImage
代替....
UIImage *img = [UIImage imageWithCGImage:[repr fullScreenImage]];
答案 5 :(得分:1)
回答问题(在 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's 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)")
}
}
答案 6 :(得分:0)
使用照片库(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
}
];
}