Get the last saved Photo in photo album - ios

I use AVFoundation framework for taking photo and save it to photoAlbum:
- (void)captureStillImage
{
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in [[self stillImageOutput] connections]) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo]) {
videoConnection = connection;
break;
}
}
if (videoConnection) {
break;
}
}if ([videoConnection isVideoOrientationSupported])
[videoConnection setVideoOrientation:self.orientation];
NSLog(#"about to request a capture from: %#", [self stillImageOutput]);
[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection
completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error)
{
ALAssetsLibraryWriteImageCompletionBlock completionBlock = ^(NSURL *assetURL, NSError *error) {
if (error) {
NSLog(#"ERROR!!!");
}
};
if (imageDataSampleBuffer != NULL)
{
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
UIImage *image = [[UIImage alloc] initWithData:imageData];
[library writeImageToSavedPhotosAlbum:[image CGImage]
orientation:(ALAssetOrientation)[image imageOrientation]
completionBlock:completionBlock];
[[NSNotificationCenter defaultCenter] postNotificationName:kImageCapturedSuccessfully object:nil];
}
}];
}
I postNotification to the method saveImageToPhotoAlbum:
- (void)saveImageToPhotoAlbum
{
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 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.imageView.image = latestPhoto;
}
}];
} failureBlock: ^(NSError *error) {
NSLog(#"No groups");
}];
}
There I used code for getting the last photo and display it on imageView, but it display not last but previous. So if I make 3 photo it will display 2, not 3.
Any ideas???
Thanks for help!

Your code is doing what it's meant to do. You have a issue with the logic of the code. YOu are posting notification before it's finished with saving image. You have to post the notification inside the completion block code of writing image to the library. And, why not just show the captured image on the imageView instead of reading it from the library??

Related

Read images from a iphone album using ALAssetsLibrary make slow

Read images from a iphone album using ALAssetsLibrary will took 30 seconds to load images of 700. Is there any other version of code using ALAssetsLibrary? My version of Code was below
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
NSLog(#"number of assets = %ld",(long)group.numberOfAssets);
[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result == nil) {
return;
}
ALAssetRepresentation *representation = [result defaultRepresentation];
BR_AssetsInfo *info = [[BR_AssetsInfo alloc] init];
info.thumbnail = [UIImage imageWithCGImage:[result thumbnail]];
info.originalImage = [UIImage imageWithCGImage:[representation fullResolutionImage]];
info.imageURLString = [[representation url] absoluteString];
info.isSelected = NO;
for (BR_AssetsInfo *asset in self.selectedAssetsArray) {
if ([asset isEqual:info]) {
info.isSelected = YES;
}
}
[self.assetsDataArray addObject:info];
[self.photosCollectionView reloadData];
}];
} failureBlock:^(NSError *error) {
if (error.code == ALAssetsLibraryAccessUserDeniedError) {
NSLog(#"user denied access, code: %li",(long)error.code);
}else{
NSLog(#"Other error code: %li",(long)error.code);
}
}];

ALAssetsLibrary addAssetsGroupAlbumWithName is not working on iOS 9

I need to add group with name "MyGroupName" in ALAssetsLibrary . So I have used below code.
ALAssetsLibrary * library = [[ALAssetsLibrary alloc] init];
__weak ALAssetsLibrary *lib = library;
[library addAssetsGroupAlbumWithName:#"MyGroupName" resultBlock:^(ALAssetsGroup *group) {
[lib enumerateGroupsWithTypes:ALAssetsGroupAlbum
usingBlock:^(ALAssetsGroup *g, BOOL *stop)
{
if ([[g valueForProperty:ALAssetsGroupPropertyName] isEqualToString:#"MyGroupName"]) {
NSLog(#"group created with name 'MyGroupName'");
}
}failureBlock:^(NSError *error){
NSLog(#"failure %#",error);
}
];
} failureBlock:^(NSError *error) {
NSLog(#"failure %#",error);
}];
but inside "enumerateGroupsWithTypes" , group "g" is always nil in iOS 9.3.1 (iphone 6). its working correctly and group created with name "MyGroupName" on iOS 9.3.1 iphone 5. I want to know why above code is not working on iphone 6 and is there any solution to make it work ?
Please help me. Thanks in advance
1) First Import
#import <Photos/Photos.h>
#import <Photos/PHAsset.h>
#import <AssetsLibrary/AssetsLibrary.h>
2) Set property for ALAsset
#property (nonatomic, strong) ALAssetsLibrary* assetsLibrary;
3) Then allocate ALAsset library in your .m file
- (ALAssetsLibrary*)assetsLibrary
{
if (!_assetsLibrary) {
_assetsLibrary = [[ALAssetsLibrary alloc] init];
[ALAssetsLibrary disableSharedPhotoStreamsSupport];
}
return _assetsLibrary;
}
4 ) Now create method for save image to custom album
- (void)saveImageDatas:(UIImage*)imageDatas toAlbum:(NSString*)album withCompletionBlock:(void(^)(NSError *error))block
{
` if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
NSMutableArray* assets = [[NSMutableArray alloc]init];
PHAssetChangeRequest* assetRequest;
#autoreleasepool {
assetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:imageDatas];
[assets addObject:assetRequest.placeholderForCreatedAsset];
}
__block PHAssetCollectionChangeRequest* assetCollectionRequest = nil;
PHFetchResult* result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
[result enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
PHAssetCollection* collection = (PHAssetCollection*)obj;
if ([collection isKindOfClass:[PHAssetCollection class]]) {
if ([[collection localizedTitle] isEqualToString:album]) {
assetCollectionRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection];
[assetCollectionRequest addAssets:assets];
*stop = YES;
}
}
}];
if (assetCollectionRequest == nil) {
assetCollectionRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:album];
[assetCollectionRequest addAssets:assets];
}
}
completionHandler:^(BOOL success, NSError *error) {
if (block) {
block(error);
}
}];
}
else {
__weak ALAssetsLibrary* lib = [self assetsLibrary];
[[self assetsLibrary] writeImageDataToSavedPhotosAlbum:UIImageJPEGRepresentation(imageDatas, 1.0) metadata:nil completionBlock:^(NSURL* assetURL, NSError* error) {
if (error != nil) {
return;
}
__block BOOL albumWasFound = NO;
[lib enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:^(ALAssetsGroup* group, BOOL* stop) {
if ([[group valueForProperty:ALAssetsGroupPropertyName] isEqualToString:album]) {
albumWasFound = YES;
[lib assetForURL:assetURL resultBlock:^(ALAsset* asset){
[group addAsset:asset];
if (block) {
block(nil);
}
}failureBlock:^(NSError* error) {
if (block) {
block(error);
}
}];
return;
}
if (group == nil && albumWasFound == NO) {
[lib addAssetsGroupAlbumWithName:album resultBlock:^(ALAssetsGroup* group) {
} failureBlock:^(NSError* error) {
[lib assetForURL:assetURL resultBlock:^(ALAsset* asset){
[group addAsset:asset];
if (block) {
block(nil);
}
}failureBlock:^(NSError* error) {
if (block) {
block(error);
}
}];
}];
}
} failureBlock:^(NSError* error) {
if (block) {
block(error);
}
}];
}];
}
}
5 ) Now call this method to save the image like
[self saveImageDatas:myimage toAlbum:#"MyGroupName" withCompletionBlock:^(NSError *error) {
if (!error) {
NSLog(#"Sucess");
}
}];
"myimage" is your image that you want to save.
Please try this on:
ALAssetsLibrary* libraryFolder = [[ALAssetsLibrary alloc] init];
[libraryFolder addAssetsGroupAlbumWithName:#"My Album" resultBlock:^(ALAssetsGroup *group)
{
NSLog(#"Adding Folder:'My Album', success: %s", group.editable ? "Success" : "Already created: Not Success");
} failureBlock:^(NSError *error)
{
NSLog(#"Error: Adding on Folder");
}];
Or Please check this link also
http://www.touch-code-magazine.com/ios5-saving-photos-in-custom-photo-album-category-for-download/

Get All Images from cameraroll asynchrously

I want to get all images from cameraroll asynchrously
Now I am using that code but my application got hanged untill all the images retrieved , I noticed in instigram or other application it doen't take time to load picture from camerroll.
-(void)getAllPictures
{
NSLog(#"i m in ");
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) {
NSLog(#"i m in block");
if(result != nil) {
if([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) {
NSLog(#"result not nill");
[assetURLDictionaries addObject:[result valueForProperty:ALAssetPropertyURLs]];
NSURL *url= (NSURL*) [[result defaultRepresentation]url];
NSLog(#"url=%#",url);
[library assetForURL:url
resultBlock:^(ALAsset *asset) {
[mutableArray addObject:[UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage]]];
imageArray=[[NSArray alloc] initWithArray:mutableArray];
[self allPhotosCollected:imageArray];
if ([mutableArray count]==count)
{NSLog(#"condition %lu , %i",(unsigned long)mutableArray.count,count);
imageArray=[[NSArray alloc] initWithArray:mutableArray];
[self allPhotosCollected:imageArray];
}
}
failureBlock:^(NSError *error){ NSLog(#"operation was not successfull!"); } ];
}
}
};
NSLog(#"image array= %#",imageArray);
NSMutableArray *assetGroups = [[NSMutableArray alloc] init];
void (^ assetGroupEnumerator) ( ALAssetsGroup *, BOOL *)= ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
NSLog(#"group not nill");
[group enumerateAssetsUsingBlock:assetEnumerator];
[assetGroups addObject:group];
count=(int)[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);
[_collection_view reloadData];
/*
CGRect collectionFrame = self.collection_view.frame;
collectionFrame.size.height=700;
collectionFrame.size.width=320;*/
self.verticalLayoutConstraint.constant = 700;
//self.collection_view.frame=collectionFrame;
}
Try like this .. Its increasing fast speed. If you will get all images in array then it will crashing your application while using iPhone & iPad that contain 1000+ photos. So Try like this.
library = [[ALAssetsLibrary alloc] init];
if (library == nil)
library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop)
{
if (asset)
{
[imageArray addObject:asset];
[collectionViewObj reloadData];
}
}];
}
failureBlock:^(NSError *error)
{
UIAlertView *alertViewObj = [[UIAlertView alloc]initWithTitle:#"Max6Miz does not have access to your photos" message:#"You can enable access in Settings" delegate:self cancelButtonTitle:nil otherButtonTitles:#"Settings",#"Ok", nil];
[alertViewObj show];
NSLog(#"error");
}];
Show your image in your delegate function like this using this collectionView cellForItemAtIndexPath
ALAsset *asset = (ALAsset *)imageArray[indexPath.row];
UIImage *showingImage = [UIImage imageWithCGImage:[asset thumbnail]];
Please use new modern Photos framework which is available from iOS 8.0. I've tested it on 50k photos and 1.5k videos stored in hundreds of albums at my own iCloud Photo Library. It works fast and allows to track and animate changes of albums and assets.
Here is nice article to start with Photos framework: https://www.objc.io/issues/21-camera-and-photos/the-photos-framework/

saving image to custom photo album in iOS7

I'm trying to save a photo taken with the camera to a custom photo album in iOS7.
my code looks like this:
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
__block ALAssetsGroup* folder;
[library enumerateGroupsWithTypes:ALAssetsGroupAlbum
usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
if ([[group valueForProperty:ALAssetsGroupPropertyName] isEqualToString:#"UrbanAlphabets"])
{
folder = group;
}
}
failureBlock:^(NSError* error)
{
// Error handling.
}];
[library writeImageToSavedPhotosAlbum:(__bridge CGImageRef)(image)
metadata:nil
completionBlock:^(NSURL* assetURL, NSError* error)
{
if (error.code == 0)
{
// Get the asset
[library assetForURL:assetURL
resultBlock:^(ALAsset *asset)
{
// Assign the photo to the album
[folder addAsset:asset];
NSLog(#"success");
}
failureBlock:^(NSError* error)
{
// Error handling.
NSLog(#"error1");
}];
}
else
{
// Error handling.
NSLog(#"error");
}
}];
and actually the console logs "success", so I guess everything should be fine, but it doesn't put the photo into the folder... I pretty much copypasted the code from here
http://www.ggkf.com/iphone/save-a-photo-to-a-folder-in-photo-library
any ideas?
this made it work
//write to photo library
NSString *albumName=#"Urban Alphabets";
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
__block ALAssetsGroup* groupToAddTo;
[library enumerateGroupsWithTypes:ALAssetsGroupAlbum
usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if ([[group valueForProperty:ALAssetsGroupPropertyName] isEqualToString:albumName]) {
groupToAddTo = group;
}
}
failureBlock:^(NSError* error) {
}];
CGImageRef img = [croppedImage CGImage];
[library writeImageToSavedPhotosAlbum:img
metadata:nil
completionBlock:^(NSURL* assetURL, NSError* error) {
if (error.code == 0) {
// try to get the asset
[library assetForURL:assetURL
resultBlock:^(ALAsset *asset) {
// assign the photo to the album
[groupToAddTo addAsset:asset];
}
failureBlock:^(NSError* error) {
}];
}
else {
}
}];

how to save UIImage in photos album using a custom name for the image

i am trying to save UIImage in the photos album of iPad with a custom name for each UIImage. I searched a lot and i realised that it is possible if i save them at the documents directory but not in the photos album. I was wondering if you could suggest a solution for that , please? Thank you in advance, best regards
To save it with a custom name I would use the following code:
// I do this in the didFinishPickingImage:(UIImage *)img method
// Build NSData in memory from the btnImage...
NSData* imageData = UIImageJPEGRepresentation(img, 1.0);
// Save to the default Apple (Camera Roll) folder.
[imageData writeToFile:#"/private/var/mobile/Media/DCIM/100APPLE/customImageFilename.jpg" atomically:NO];
In order to save an screenshot in the device in a custom album name use the following code:
- (void)createScreenshotAndSaveInACustomAlbum {
DebugLog(#"");
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
} else {
UIGraphicsBeginImageContext(self.view.bounds.size);
}
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library addAssetsGroupAlbumWithName:#"My Photo Album" resultBlock:^(ALAssetsGroup *group) {
// Checks if group previously created
if(group == nil){
// Enumerate albums
[library enumerateGroupsWithTypes:ALAssetsGroupAlbum
usingBlock:^(ALAssetsGroup *g, BOOL *stop)
{
// If the album is equal to our album
if ([[g valueForProperty:ALAssetsGroupPropertyName] isEqualToString:#"My Photo Album"]) {
// Save image
[library writeImageDataToSavedPhotosAlbum:UIImagePNGRepresentation(image) metadata:nil
completionBlock:^(NSURL *assetURL, NSError *error) {
// Then get the image asseturl
[library assetForURL:assetURL resultBlock:^(ALAsset *asset) {
// Put it into our album
[g addAsset:asset];
} failureBlock:^(NSError *error) {
}];
}];
}
} failureBlock:^(NSError *error){ }];
} else {
// Save image directly to library
[library writeImageDataToSavedPhotosAlbum:UIImagePNGRepresentation(image) metadata:nil
completionBlock:^(NSURL *assetURL, NSError *error) {
[library assetForURL:assetURL resultBlock:^(ALAsset *asset) {
[group addAsset:asset];
} failureBlock:^(NSError *error) { }];
}];
}
} failureBlock:^(NSError *error) { }];
}
Hope this helps!

Resources