I am currently developing an iPhone application that implements face detection and tagging. I am using the SQLite database to store the tags and the url of corresponding images. Now, while retrieving I will be implementing some logic to filter out the desired images based on the tag and getting the set of URLs of images(from the Db) that match this tag.
(Asset Library URL's of the form - assets-library://asset/asset.JPG?id=79465E8C-53B9-40D6-B11C-07A1856E9093&ext=JPG)
My question is, if I have an array of NSURL's, how do I load a custom image picker using ALAssetsLibrary with only the URL's present in the array and not all the images from the default photo library?
I have read how to load an image from a URL based on this answer:
https://stackoverflow.com/a/18888938
for this question:
display image from URL retrieved from ALAsset in iPhone
How do I run a single loop over my array of URL's to load these images using ALAssets into a custom UICollectionView to replicate the ImagePickerController?
Have a look on this sample code from apple to implement a custom image picker.
/**
* This method is used to get all images from myAlbum
* folder in device if getAlbumImages is set to 1
* else loads all images from devices library
*/
-(void)readImages:(int)getAlbumImages
{
imageArray = [[NSArray alloc] init];
mutableArray =[[NSMutableArray alloc]init];
NSMutableArray* assetURLDictionaries = [[NSMutableArray alloc] init];
library = [[ALAssetsLibrary alloc] init];
if(getFolderImages == 1) {
// Load images from Shareaflash folder
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *documentdataPath = [documentsDirectory stringByAppendingPathComponent:#"myFolder"];
NSLog(#"documentdataPath %#",documentdataPath);
} else {
// Load all images
}
void (^assetEnumerator)( ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result != nil) {
if([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) {
[assetURLDictionaries addObject:[result valueForProperty:ALAssetPropertyURLs]];
NSURL *url = (NSURL*) [[result defaultRepresentation]url];
[library assetForURL:url resultBlock:^(ALAsset *asset) {
[mutableArray addObject:asset];
if ([mutableArray count]==count)
{
imageArray =[[NSArray alloc] initWithArray:mutableArray];
[self allPhotosCollected:imageArray];
}
}
failureBlock:^(NSError *error){ NSLog(#"operation was not successfull!"); } ];
}
}
};
NSMutableArray *assetGroups = [[NSMutableArray alloc] init];
void (^ assetGroupEnumerator) ( ALAssetsGroup *, BOOL *)= ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
[group enumerateAssetsUsingBlock:assetEnumerator];
[assetGroups addObject:group];
count=[group numberOfAssets];
}
};
assetGroups = [[NSMutableArray alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:assetGroupEnumerator
failureBlock:^(NSError *error) { NSLog(#"There is an error"); }];
}
Related
I want to show all images from device to my app in uicollectionview.
and want to select multiple images from uicollectionview. I have watched numbers of programs.ELCImagePickerController
but i cant get it correctly.
please help me...
thank you
this links works fine...Multi-Select ImagePicker
but how can i get selected images into an array from button Done..
When I press Done button image shown in array like this....
<UIImage: 0x7fca78772510>, {485, 303}
so, how can i get this image in my collection view.. help me guys....
Get all image from gallery
View Controller header(.h) file..
#import <UIKit/UIKit.h>
#include <AssetsLibrary/AssetsLibrary.h>
#interface getPhotoLibViewController : UIViewController
{
ALAssetsLibrary *library;
NSArray *imageArray;
NSMutableArray *mutableArray;
}
-(void)allPhotosCollected:(NSArray*)imgArray;
#end
implementation file
declare global count variable as
static int count=0;
#implementation getPhotoLibViewController
-(void)getAllPictures
{
imageArray=[[NSArray alloc] init];
mutableArray =[[NSMutableArray alloc]init];
NSMutableArray* assetURLDictionaries = [[NSMutableArray alloc] init];
library = [[ALAssetsLibrary alloc] init];
void (^assetEnumerator)( ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result != nil) {
if([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) {
[assetURLDictionaries addObject:[result valueForProperty:ALAssetPropertyURLs]];
NSURL *url= (NSURL*) [[result defaultRepresentation]url];
[library assetForURL:url
resultBlock:^(ALAsset *asset) {
[mutableArray addObject:[UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage]]];
if ([mutableArray count]==count)
{
imageArray=[[NSArray alloc] initWithArray:mutableArray];
[self allPhotosCollected:imageArray];
}
}
failureBlock:^(NSError *error){ NSLog(#"operation was not successfull!"); } ];
}
}
};
NSMutableArray *assetGroups = [[NSMutableArray alloc] init];
void (^ assetGroupEnumerator) ( ALAssetsGroup *, BOOL *)= ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
[group enumerateAssetsUsingBlock:assetEnumerator];
[assetGroups addObject:group];
count=[group numberOfAssets];
}
};
assetGroups = [[NSMutableArray alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:assetGroupEnumerator
failureBlock:^(NSError *error) {NSLog(#"There is an error");}];
}
-(void)allPhotosCollected:(NSArray*)imgArray
{
//write your code here after getting all the photos from library...
NSLog(#"all pictures are %#",imgArray);
}
#end
Use getAllPicture method to get photos from photo library.
OR You can have a look at this blog http://mutiselectimagepicker.blogspot.in/2014/08/imageselect-to-allow-multiple-selection.html
I have fetched the images and videos from gallery, it works fine when the number of videos and images is minimum,but when the number of images and videos is large, it blocks the main thread.
-(void)viewDidAppear:(BOOL)animated{
[NSThread sleepForTimeInterval:1];
// call the same method on a background thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self getAllVideosAndImages];
});
}
To gat Images and Videos From Asset
-(void)getAllVideosAndImages{
NSMutableArray *assetGroups = [[NSMutableArray alloc] init];
assetGroups = [[NSMutableArray alloc] init];
library = [[ALAssetsLibrary alloc] init];
NSUInteger groupTypes = ALAssetsGroupAll;
void (^assetEnumerator)
( ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result != nil) {
if([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo]||[[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) {
ALAssetRepresentation *rep = [result defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
if (iref) {
//GET DATE
NSDate *myDate = [result valueForProperty:ALAssetPropertyDate];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMM dd,YYYY"];
NSString *realDateStr = [dateFormatter stringFromDate:myDate];
//GET IMG AND VIDEO
UIImage *largeimage = [UIImage imageWithCGImage:iref];
NSData *webData = UIImagePNGRepresentation(largeimage);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"img%zd.mov",imgName]];
imgName=imgName+1;
[webData writeToFile:localFilePath atomically:YES];
Para_ImageSet *objImgSet=[Para_ImageSet new];
objImgSet.imagePath=localFilePath;
objImgSet.imageDate=realDateStr;
// [yArrayOfAllImges addObject:objImgSet];
if ([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo]) {
objImgSet.is_video=YES;
}
else
{
objImgSet.is_video=NO;
}
if ([tempDate isEqualToString:#""]) {
yArrayOfImagesWithDate=[NSMutableArray new];
[yArrayOfImagesWithDate addObject:objImgSet];
tempDate=realDateStr;
}else
{
//GATE IMAGE COUNT
if ([realDateStr isEqualToString:tempDate]) {
//DO NOTHING
[yArrayOfImagesWithDate addObject:objImgSet];
}
else
{
[yArrayOFNNestedImgs addObject:yArrayOfImagesWithDate];
NSLog(#" ----------ImagesWithDate =%zd, %#",yArrayOfImagesWithDate.count,tempDate);
yArrayOfImagesWithDate=[NSMutableArray new];
[yArrayOfImagesWithDate addObject:objImgSet];
tempDate=realDateStr;
}
}
}
}
}
[self.tableView reloadData];
};
void (^ assetGroupEnumerator) ( ALAssetsGroup *, BOOL *)= ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
[group enumerateAssetsUsingBlock:assetEnumerator];
[assetGroups addObject:group];
// NSNumber *countObj = [NSNumber numberWithInt:count];
NSLog(#" ----------ImagesWithDate =%zd, %#",yArrayOfImagesWithDate.count,tempDate);
[yArrayOFNNestedImgs addObject:yArrayOfImagesWithDate];
NSLog(#" ----------Count =%zd",yArrayOFNNestedImgs.count);
[NSThread sleepForTimeInterval:10];
// update UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
};
[library enumerateGroupsWithTypes:groupTypes
usingBlock:assetGroupEnumerator
failureBlock:^(NSError *error) {NSLog(#"A problem occurred");}];
}
Please Suggest..Thanks in advance.
[NSThread sleepForTimeInterval:1]; is blocking main thread for a second. It's not needed.
You could use [self performSelectorInBackground:#selector(getAllVideosAndImages) withObject:nil];
Also, wrap first [self.tableView reloadData]; in
dispatch_async(dispatch_get_main_queue(), ^{
...
}); too
In order to lazily load the resources, here is the recommended approach:
Download URLs of all resources and store them into your container (array / objects etc)
Fire a NSURLSessionTask (post iOS 7 only) which runs async on background queue. If you are below iOS 7, you can use NSURLConnection SendAsynchronousRequest API - it's deprecated in iOS 9 so you better get rid of that soon.
Process your downloaded resources while on background queue - store audio/image files, create UIImage from NSData, and so on.
Come back to main queue, then update the relevant UI part with downloaded content. If audio/video, play it. If UIImage, display it.
Here - the entire approach is described in my tutorial.
I want to show all images from device to my app in uicollectionview.
and want to select multiple images from uicollectionview. I have watched numbers of programs.ELCImagePickerController
but i cant get it correctly.
please help me...
thank you
this links works fine...Multi-Select ImagePicker
but how can i get selected images into an array from button Done..
When I press Done button image shown in array like this....
<UIImage: 0x7fca78772510>, {485, 303}
so, how can i get this image in my collection view.. help me guys....
Get all image from gallery
View Controller header(.h) file..
#import <UIKit/UIKit.h>
#include <AssetsLibrary/AssetsLibrary.h>
#interface getPhotoLibViewController : UIViewController
{
ALAssetsLibrary *library;
NSArray *imageArray;
NSMutableArray *mutableArray;
}
-(void)allPhotosCollected:(NSArray*)imgArray;
#end
implementation file
declare global count variable as
static int count=0;
#implementation getPhotoLibViewController
-(void)getAllPictures
{
imageArray=[[NSArray alloc] init];
mutableArray =[[NSMutableArray alloc]init];
NSMutableArray* assetURLDictionaries = [[NSMutableArray alloc] init];
library = [[ALAssetsLibrary alloc] init];
void (^assetEnumerator)( ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result != nil) {
if([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) {
[assetURLDictionaries addObject:[result valueForProperty:ALAssetPropertyURLs]];
NSURL *url= (NSURL*) [[result defaultRepresentation]url];
[library assetForURL:url
resultBlock:^(ALAsset *asset) {
[mutableArray addObject:[UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage]]];
if ([mutableArray count]==count)
{
imageArray=[[NSArray alloc] initWithArray:mutableArray];
[self allPhotosCollected:imageArray];
}
}
failureBlock:^(NSError *error){ NSLog(#"operation was not successfull!"); } ];
}
}
};
NSMutableArray *assetGroups = [[NSMutableArray alloc] init];
void (^ assetGroupEnumerator) ( ALAssetsGroup *, BOOL *)= ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
[group enumerateAssetsUsingBlock:assetEnumerator];
[assetGroups addObject:group];
count=[group numberOfAssets];
}
};
assetGroups = [[NSMutableArray alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:assetGroupEnumerator
failureBlock:^(NSError *error) {NSLog(#"There is an error");}];
}
-(void)allPhotosCollected:(NSArray*)imgArray
{
//write your code here after getting all the photos from library...
NSLog(#"all pictures are %#",imgArray);
}
#end
Use getAllPicture method to get photos from photo library.
OR You can have a look at this blog http://mutiselectimagepicker.blogspot.in/2014/08/imageselect-to-allow-multiple-selection.html
I've just started a new project where I want the user to be able to pick one of the images in the devices gallery.
I am trying to achieve this by using an ImageView and a UIStepper.
I want to write all images inside the gallery into an array and have the imageView navigate through the array with the + and - buttons of the stepper (selecting the current array position +1 or -1 depending on click).
OK as per prior discussion, here is the project: AssetLibraryPhotosViewer
Have not done an extensive testing, though does seem to run OK both on simulator and real device
#Exothug, to give you an idea of how to enumerate the device library accessing full screen photos:
ALAssetsLibrary* assetLibrary = [[ALAssetsLibrary alloc] init];
[assetLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group) {
[group enumerateAssetsUsingBlock:^(ALAsset* asset, NSUInteger index, BOOL* innerstop) {
if (asset) {
ALAssetRepresentation *rep = [asset defaultRepresentation];
CGImageRef iref = [rep fullScreenImage];
if (iref) {
UIImage *image = [UIImage imageWithCGImage:iref scale:rep.scale
orientation:(UIImageOrientation)rep.orientation];
// process the image here
}
}
}];
}
} failureBlock:^(NSError *error) {
NSLog(#"failure: %#", [error localizedDescription]);
}];
you can just process the image via adding it to your array, however depending on number of images in the library it might not be most effective. an alternative approach would be using images URL / indexes to iterate through the library, fetching the image from the library as its needed for display in your ImageView
Maybe try something like this, choose the directory if you want a specific group of images.
NSMutableArray *result = [NSMutableArray array];
[[[NSBundle mainBundle] pathsForResourcesOfType:#"png" inDirectory:nil] enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL *stop) {
NSString *path = [obj lastPathComponent];
[result addObject:path];
];
I thought that , You just need to retrieve the Photos of Camera Roll from Your device .
If so , Try with this :
ALAssetsLibrary
void (^assetEnumerator)(struct ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result != NULL) {
NSLog(#"See Asset: %#", result);
}
};
void (^assetGroupEnumerator)(struct ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
[group enumerateAssetsUsingBlock:assetEnumerator];
}
};
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:assetGroupEnumerator
failureBlock: ^(NSError *error) {
NSLog(#"Failure");
}];
OR
//Get camera roll images
- (void)updateLastPhotoThumbnail {
ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
[assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
NSInteger numberOfAssets = [group numberOfAssets];
if (numberOfAssets > 0) {
NSLog(#"numberOfPictures: %d",numberOfAssets);
//NSInteger lastIndex = numberOfAssets - 1;
int i = 0;
for (i = 0; i <= numberOfAssets-1; i++) {
[group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:i] options:0 usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
UIImage *thumbnail = [UIImage imageWithCGImage:[result thumbnail]];
NSLog(#"theObject!!!! -- (%d) %#",i,thumbnail);
[cameraRollPictures addObject:thumbnail];
}];
}
}
} failureBlock:^(NSError *error) {
NSLog(#"error: %#", error);
}];
I enumerate all assets groups using ALAssetsLibrary
Here is code:
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
void (^enumerate)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop)
{
if (group == nil)
{
// enumerated all albums..
}
// I hot to check if group is Camera Roll ?
};
[library enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:enumerate
failureBlock:nil];
How to check if some current enumerated is CameraRoll?
Edit: As i tested it was always the last, using this enumerating. But i am not sure if it is the rule, are there any references that i missed?
To get photos from camera roll use ALAssetsGroupSavedPhotos while enumerating assets library:
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
usingBlock:enumerate
failureBlock:nil];
To detect what group you currently get:
if ([[group valueForProperty:#"ALAssetsGroupPropertyType"] intValue] == ALAssetsGroupSavedPhotos)
{
NSLog(#"Camera roll");
}
imageArray = [[NSArray alloc] init];
NSMutableArray*mutableArray =[[NSMutableArray alloc]init];
NSMutableArray* assetURLDictionaries = [[NSMutableArray alloc] init];
ALAssetsLibrary*library = [[ALAssetsLibrary alloc] init];
void (^enumerate)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop)
{
if ([[group valueForProperty:#"ALAssetsGroupPropertyType"] intValue] == ALAssetsGroupSavedPhotos)
{
NSLog(#"Camera roll");
[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
ALAssetRepresentation *rep = [result defaultRepresentation];
NSLog(#"Asset Name ----> %#",rep.filename);
}];
}
// I hot to check if group is Camera Roll ?
};
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
usingBlock:enumerate
failureBlock:nil];