English 中文(简体)
从照片中获得最后形象?
原标题:Get last image from Photos.app?

我看到了其他的照片,即你可以从照片上进口最后的照片,供快速使用,但我知道,我只知道如何获得图像,而不是最后的图像(最近的一次)。 谁能向我展示最后的形象?

最佳回答

该密码扫描将从照相机显示的最新图像(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");
}];

<>9>

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

                                           });
                                       }];
问题回答

iBrad的回答对我来说几乎是完美的。 唯一的例外是,它正在按原方向归还图像(例如,倒塌,90°等)。

为确定这一点,我简单修改了<代码>full ResolutionImage至fullScreenImage

这里:

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

如今,它已经做了治疗。

iBrad 的例子包括Si-8型狙击机,该车显然行之有效,但我发现自己被他描述的返回类型混为一谈。 这里是 gr弄最后形象的幻灯,包括版本和规模要求的选择。

值得注意的是,能够要求具体版本(原始、当前)和规模。 在我的案件中,由于我希望将返回的形象应用到一个县,我要求该县的大小和规模,以适应适用于该州的1米:

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

                                           });
                                       }];

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

}

如果你需要更快,你也可以使用<代码>。 PHImage RequestOptions

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

感谢您的答复。

只是想指出,当用户没有照片上图像时,该特例会发生错误预防(奇怪的情况一知道):

    // 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
    }

Liam.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:

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.

我发现,我感到难堪的是,我只想让我看到一个比我更长的时间。 也许会节省别人的时间。

这条线在<代码>后缺失:

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

在iBrad的答复基础上,这里的“快速”版;“超仓”版在SOS8.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
    })
}

<>:本说明要求<8.0+>。 保证将照片框架连接起来,并在你的档案中添加“进口照片”。

这里的版本是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

             }
        }
    }

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.

- (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) {
    }];
}

Xamarin.iOS版本接受回答(如何获得最后形象),包括从其他答复中发出的所有通知:

  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);
            });
    }

这是一种非常冷静的做法,但其中一个问题是,你必须能够即时播放PHPhotoLibrary和其他PHPhoto课程,因为否则,第7期将出现联系错误。 X.X 只是想指出这一点,因为我现在谈谈这些问题。

我还认为,在照片框架中,你必须软弱环节,才能把镜头放在这两个装置上,使用SOS8.X.X和7.X。 安装了十台(尽管我尚未对此进行测试)。

我正在讨论的问题涉及如何在常年时即时处理PHPhotoLibrary。 是否有任何人为此制定法规?

Actually for the app that I was working on, I did have to finally write runtime code for instantiating PHPhotoLibrary class and calling PHotos framework methods so the app would run on both iOS 7.x.x and iOS 8.x.x. Someone else may run into the same issues so I provided the code below ->

// PHPhotoLibrary_class will only be non-nil on iOS 8.x.x
Class PHPhotoLibrary_class = NSClassFromString(@"PHPhotoLibrary");

if (PHPhotoLibrary_class) {

   /**
    *
    iOS 8..x. . code that has to be called dynamically at runtime and will not link on iOS 7.x.x ...

    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title];
    } completionHandler:^(BOOL success, NSError *error) {
        if (!success) {
            NSLog(@"Error creating album: %@", error);
        }
    }];
    */

    // dynamic runtime code for code chunk listed above            
    id sharedPhotoLibrary = [PHPhotoLibrary_class performSelector:NSSelectorFromString(@"sharedPhotoLibrary")];

    SEL performChanges = NSSelectorFromString(@"performChanges:completionHandler:");

    NSMethodSignature *methodSig = [sharedPhotoLibrary methodSignatureForSelector:performChanges];

    NSInvocation* inv = [NSInvocation invocationWithMethodSignature:methodSig];
    [inv setTarget:sharedPhotoLibrary];
    [inv setSelector:performChanges];

    void(^firstBlock)() = ^void() {
        Class PHAssetCollectionChangeRequest_class = NSClassFromString(@"PHAssetCollectionChangeRequest");
        SEL creationRequestForAssetCollectionWithTitle = NSSelectorFromString(@"creationRequestForAssetCollectionWithTitle:");
        [PHAssetCollectionChangeRequest_class performSelector:creationRequestForAssetCollectionWithTitle withObject:albumName];

    };

    void (^secondBlock)(BOOL success, NSError *error) = ^void(BOOL success, NSError *error) {
       if (success) {
           [assetsLib enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
               if (group) {
                   NSString *name = [group valueForProperty:ALAssetsGroupPropertyName];
                   if ([albumName isEqualToString:name]) {
                       groupFound = true;
                       handler(group, nil);
                   }
               }
           } failureBlock:^(NSError *error) {
               handler(nil, error);
           }];
       }

       if (error) {
           NSLog(@"Error creating album: %@", error);
           handler(nil, error);
       }
   };

   // Set the first and second blocks.
   [inv setArgument:&firstBlock atIndex:2];
   [inv setArgument:&secondBlock atIndex:3];

   [inv invoke];

}
else {   
   // code that always creates an album on iOS 7.x.x but fails
   // in certain situations such as if album has been deleted
   // previously on iOS 8...x. .              
   [assetsLib addAssetsGroupAlbumWithName:albumName
       resultBlock:^(ALAssetsGroup *group) {
       handler(group, nil);
   } failureBlock:^(NSError *error) {
       NSLog( @"Failed to create album: %@", albumName);
       handler(nil, error);
   }];
}

下述法典与OS7和OS8合作。 它还检查了过滤器中是否有图像。 在你执行该守则之前,你应检查该册的许可:

// 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");
    }];
}  

(该代码是here。)





相关问题
List Contents of Directory in a UITableView

I am trying to list the contents of Ringtones directory in a TableView, however, I am only getting the last file in the directory in ALL cells, instead of file per cell. This is my code: - (...

iPhone NSUserDefaults persistance difficulty

In my app i have a bunch of data i store in the NSUserdefaults. This information consists of an NSObject (Object1) with NSStrings and NSNumbers and also 2 instances of yet another object (Object2). ...

Writing a masked image to disk as a PNG file

Basically I m downloading images off of a webserver and then caching them to the disk, but before I do so I want to mask them. I m using the masking code everyone seems to point at which can be found ...

Resize UIImage with aspect ratio?

I m using this code to resize an image on the iPhone: CGRect screenRect = CGRectMake(0, 0, 320.0, 480.0); UIGraphicsBeginImageContext(screenRect.size); [value drawInRect:screenRect blendMode:...

Allowing interaction with a UIView under another UIView

Is there a simple way of allowing interaction with a button in a UIView that lies under another UIView - where there are no actual objects from the top UIView on top of the button? For instance, ...

热门标签