I use ALAssetsLibrary to enumerate assets from the photo library but there is one problem. If I'm inside the block (the one for enumeration) I can access the thumbnail image without problem. However if I store the ALAsset in a collection and try to access the thumbnail image at some point later its 0x00000000.
Why this? Is there a better way to access individual images later?
My code works like this:
assets = [[NSMutableArray alloc] init];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:assetGroupEnumerator
failureBlock:^(NSError *error) {NSLog(#"bla bla bla ... problem");}];
with
void (^assetGroupEnumerator) (ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop)
{
if(group != nil)
{
// extract every asset from goup
[group enumerateAssetsUsingBlock:assetEnumerator];
}
};
and
void (^assetEnumerator) (ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
[assets addObject:result];
}
I found the problem being the (all to early) release of the ALAssetsLibrary. I should not give it up as long as I need the thumbnails and whatever else and simply keep its reference.
Related
I am iOS developer i want to get all images from library, without UIImagepickercontroller,and take first 10 images
Any ideas?
There are lots of example out der which will guide you how to get images from ALAssetLibrary
https://www.cocoacontrols.com/search?q=image+picker.
Below is example to get the latest image from ImagePicker
- (void)latestPhotoWithCompletion:(void (^)(UIImage *photo))completion
{
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]];
// completion
completion(img);
// 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.
}];
}
Usage
__weak __typeof(self)wSelf = self;
[self latestPhotoWithCompletion:^(UIImage *photo) {
UIImageRenderingMode renderingMode = YES ? UIImageRenderingModeAlwaysOriginal : UIImageRenderingModeAlwaysTemplate;
[wSelf.switchCameraBut setImage:[photo imageWithRenderingMode:renderingMode] forState:UIControlStateNormal];
}];
In apps such as Tweetbot there is a "choose most recent picture" function. I would like to know what the path is for the most recent image in the camera roll.
I know that when I pick an image from camera roll manually, the code to retrieve said image looks like this:
UIImage* image = [info valueForKey:#"UIImagePickerControllerOriginalImage"];
What I do not know is what to put in the info valueForKey for the newest picture. I googled extensively and found nada. I know the rules- I am supposed to show what I have tried, but I am at a loss as to what to try, as I am finding zilch in my research and am not familiar with file path related programming.
I read the docs and found nothing of use. Thank you!
In this example, the most recent photo is stored in the UIImage named latestPhoto. Hope this helps!
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop)
{
if (alAsset)
{
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
UIImage *latestPhoto = [UIImage imageWithCGImage:[representation fullScreenImage]];
}
}];
}
failureBlock: ^(NSError *error)
{
// an error has occurred
}];
I'm building an IOS applicaiton.
I'm want to get the last photo that was taken that was also took from the rugular iphone app camera and not by a third party application.
I can get the last photo from the photo library by this method:
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;
Can i some how detect if this photo was taken by the regular iphone camera applicaiton?
I am making a camera app where I want to get to all of the videos users have created on their iPhone.
Currently the code I have gets the videos from user Camera Roll only. Some my users have complained that they have multiple custom folders created under their Photo Album app and they store some videos in there. Since my code only looks at Camera Roll, it doesn't pickup the movies from their other folders. Is it possible that I can get to their other folders?
This is what I have so far.
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
[group enumerateAssetsUsingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop)
{
if (alAsset)
{
ALAssetRepresentation *representation =[alAsset defaultRepresentation];
NSURL *url = [representation url];
NSString *assetType=[alAsset valueForProperty:ALAssetPropertyType];
//videos only
if ([assetType isEqualToString:#"ALAssetTypeVideo"])
{
.....
You got to create a filter for the assets, something like this:
ALAssetsLibraryGroupsEnumerationResultsBlock listGroupBlock = ^(ALAssetsGroup *group, BOOL *stop) {
ALAssetsFilter *allVideosFilter = [ALAssetsFilter allVideos];
[group setAssetsFilter:allVideosFilter];
//...
};
Options for filters are:
- allAssets
- allVideos
- allPhotos
Hope this helps
To get media that was synced from iTunes you need to use ALAssetsGroupLibrary. Here you can find all possible variants for ALAssetsGroupType. So just change
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:...
to
[library enumerateGroupsWithTypes:(ALAssetsGroupSavedPhotos | ALAssetsGroupLibrary) usingBlock:...
This retrieves all videos, including any the user has synced from iTunes:
// Enumerate just the photos and videos by using ALAssetsGroupSavedPhotos
[library enumerateGroupsWithTypes:ALAssetsGroupAll | ALAssetsGroupLibrary
usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
if (group != nil)
{
// Within the group enumeration block, filter to enumerate just videos.
[group setAssetsFilter:[ALAssetsFilter allVideos]];
[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result) {
// Do whatever you need to with `result`
}
}];
} else {
// If group is nil, we're done enumerating
// e.g. if you're using a UICollectionView reload it here
[collectionView reloadData];
}
} failureBlock:^(NSError *error) {
// If the user denied the authorization request
NSLog(#"Authorization declined");
}];
Note the ALAssetsGroupAll | ALAssetsGroupLibrary.
According to the docs ALAssetsGroupAll is "the same as ORing together all the group types except for ALAssetsGroupLibrary". So we also add ALAssetsGroupLibrary which "includes all assets that are synced from iTunes".
I am trying to load all the files(audio, video and images) in my application using ALAssetLibrary by this piece of code:
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
// Within the group enumeration block, filter to enumerate everything.
[group setAssetsFilter:[ALAssetsFilter allAssets]];
// Accessing all the assets.
for (int i = 0;i<[group numberOfAssets] ; i++) {
[group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:i] 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];
NSURL *url = [representation url];
NSLog(#"%#",url);
AVAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
//Doing some stuff with assets
}
}];
}
}
failureBlock: ^(NSError *error) {
NSLog(#"No groups");
}];
However, this only loads video and images, not the audio files. How can I do that?
Regarding Apple.Developer ALAsset documentaion ,An ALAsset object represents a photo or a video managed by the Photo application.
Assets can have multiple representations, for example a photo which was captured in RAW and JPG. Different representations of the same asset may have different dimensions.
So i think ,ALAssetsLibrary will not retrieve what you need :)