The program flow going wrong - ios

In this code snippet the flow of program goes
out of for loop first then only goes inside the block
resultBlock:^(ALAsset *asset).
The code prints the NSLog at the bottom first then executes the block inside the loop. What's happening here?
ALAssetsLibrary *lib=[ALAssetsLibrary new];
_sizeOfSelectedImage=0;
for (int i=0; i<assets.count; i++) {
ALAsset *asset=assets[i];
FileOP *fileMgr=[[FileOP alloc]init];
NSString *baseDir=[fileMgr GetDocumentDirectory];
//STORING FILE INTO LOCAL
[lib assetForURL:asset.defaultRepresentation.url
resultBlock:^(ALAsset *asset){
ALAssetRepresentation *repr = [asset defaultRepresentation];
CGImageRef cgImg = [repr fullResolutionImage];
NSString *fname = repr.filename;
UIImage *img = [UIImage imageWithCGImage:cgImg];
NSData *data = UIImagePNGRepresentation(img);
[data writeToFile:[baseDir stringByAppendingPathComponent:fname]
atomically:YES];
//FOR LOCAL URL OF THE IMAGE
//NSString *imageURL = [baseDir stringByAppendingPathComponent:fname];
//UIImage *myImg =[UIImage imageWithContentsOfFile:imageURL];
//NSLog(#"%# URL OF IMAGE ",imageURL);
NSLog(#"Image %d has %d size",i,data.length);
_sizeOfSelectedImage +=data.length;
NSLog(#"%d is the size",_sizeOfSelectedImage);
}
failureBlock:^(NSError *error){
}];
}
NSLog(#"COPIED %lu FILE INTO LOCAL MEMORY AND TOTAL SIZE COPIED IS %d ",(unsigned long)assets.count,_sizeOfSelectedImage);

Method assetForURL:resultBlock:failureBlock: will execute the load of asset asynchronously. That's why we first have the bottom NSLog executed and then in Block. If you want it to be executed synchronously, do it like this:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0) ^{
ALAssetsLibrary *lib=[ALAssetsLibrary new];
_sizeOfSelectedImage=0;
dispatch_group_t group = dispatch_group_create();
for (int i=0;i<assets.count;i++) {
ALAsset *asset=assets[i];
FileOP *fileMgr=[[FileOP alloc]init];
NSString *baseDir=[fileMgr GetDocumentDirectory];
//STORING FILE INTO LOCAL
dispatch_group_enter(group);
[lib assetForURL:asset.defaultRepresentation.url
resultBlock:^(ALAsset *asset){
ALAssetRepresentation *repr = [asset defaultRepresentation];
CGImageRef cgImg = [repr fullResolutionImage];
NSString *fname = repr.filename;
UIImage *img = [UIImage imageWithCGImage:cgImg];
NSData *data = UIImagePNGRepresentation(img);
[data writeToFile:[baseDir stringByAppendingPathComponent:fname]
atomically:YES];
//FOR LOCAL URL OF THE IMAGE
//NSString *imageURL = [baseDir stringByAppendingPathComponent:fname];
//UIImage *myImg =[UIImage imageWithContentsOfFile:imageURL];
//NSLog(#"%# URL OF IMAGE ",imageURL);
NSLog(#"Image %d has %d size",i,data.length);
_sizeOfSelectedImage +=data.length;
NSLog(#"%d is the size",_sizeOfSelectedImage);
dispatch_group_leave(group);
}
failureBlock:^(NSError *error){
dispatch_group_leave(group);
}];
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(#"COPIED %lu FILE INTO LOCAL MEMORY AND TOTAL SIZE COPIED IS %d ",(unsigned long)assets.count,_sizeOfSelectedImage);
dispatch_async(dispatch_get_main_queue(), ^{
// Do your call back on main thread here
});
});
Edit1: Enhanced answer from Ken
ALAssetsLibrary *lib=[ALAssetsLibrary new];
_sizeOfSelectedImage=0;
dispatch_group_t group = dispatch_group_create();
for (int i=0;i<assets.count;i++) {
ALAsset *asset=assets[i];
FileOP *fileMgr=[[FileOP alloc]init];
NSString *baseDir=[fileMgr GetDocumentDirectory];
//STORING FILE INTO LOCAL
dispatch_group_enter(group);
[lib assetForURL:asset.defaultRepresentation.url
resultBlock:^(ALAsset *asset){
ALAssetRepresentation *repr = [asset defaultRepresentation];
CGImageRef cgImg = [repr fullResolutionImage];
NSString *fname = repr.filename;
UIImage *img = [UIImage imageWithCGImage:cgImg];
NSData *data = UIImagePNGRepresentation(img);
[data writeToFile:[baseDir stringByAppendingPathComponent:fname]
atomically:YES];
//FOR LOCAL URL OF THE IMAGE
//NSString *imageURL = [baseDir stringByAppendingPathComponent:fname];
//UIImage *myImg =[UIImage imageWithContentsOfFile:imageURL];
//NSLog(#"%# URL OF IMAGE ",imageURL);
NSLog(#"Image %d has %d size",i,data.length);
_sizeOfSelectedImage +=data.length;
NSLog(#"%d is the size",_sizeOfSelectedImage);
dispatch_group_leave(group);
}
failureBlock:^(NSError *error){
dispatch_group_leave(group);
}];
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// Do your call back on main thread here
NSLog(#"COPIED %lu FILE INTO LOCAL MEMORY AND TOTAL SIZE COPIED IS %d ",(unsigned long)assets.count,_sizeOfSelectedImage);
// Your code here
});

Related

How to Display asset url In collection view ios

ALAssetsGroupEnumerationResultsBlock assetsEnumerationBlock = ^(ALAsset *result, NSUInteger index, BOOL *stop)
{
if (result) {
[assets addObject:result];
ALAssetRepresentation *rep = [result defaultRepresentation];
photoname=[rep filename];
imageurl=[rep url];
NSLog(#"result %#",result);
NSLog(#"name %#",photoname);//Img0001.Jpg
NSLog(#"name %#",imageurl);//assets-library://asset/asset.JPG?id=3B36DBC8-A2F7-4088-ADEF-A9E2FF8FD927&ext=JPG
[print addObject:photoname];
//NsuserDefaults
// NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithArray:print];
// [[NSUserDefaults standardUserDefaults] setObject:mutableArray forKey:#"test"];
retArray = [[NSMutableArray alloc] initWithArray:((NSMutableArray *) [[NSUserDefaults standardUserDefaults] objectForKey:#"test"])];
NSLog(#"res %#",retArray);
}
};
ALAssetsFilter *onlyPhotosFilter = [ALAssetsFilter allPhotos];
[self.assetsGroup setAssetsFilter:onlyPhotosFilter];
[self.assetsGroup enumerateAssetsUsingBlock:assetsEnumerationBlock];
}
You need to use the assets library to get the asset for the URL, and then get the image from the asset. Currently you are treating the asset URL as an asset rather than using the URL to get the asset:
[self.assetsLibrary assetForURL:assetURL resultBlock:^(ALAsset * asset) {
UIImage *image = [UIImage imageWithCGImage:[asset thumbnail]];
// use the image for something
}
NSURL *assetURL = notequal[indexPath.row];
[self.assetslibrary assetForURL:assetURL resultBlock:^(ALAsset * asset) {
UIImage *image = [UIImageimageWithCGImage[asset thumbnail]];
UIImageView *imageView = (UIImageView *)[cell viewWithTag:kImageViewTag];
imageView.image = thumbnail;
}];
return cell;

Get the Image (UIImage) using asset URL in iOS 7

I have some images in my Photo Album. I have already retrieved the asset urls of all of them.. I want to get a particular image using the asset url... below code gave me asset url..
ALAssetRepresentation *defaultRepresentation = [asset defaultRepresentation];
NSString *uti = [defaultRepresentation UTI];
NSURL *URL = [[asset valueForProperty:ALAssetPropertyURLs] valueForKey:uti];
Now using this url, how can I get the image(UIImage)?
Get Url by this,
NSURL *url= (NSURL*) [[asset valueForProperty:ALAssetPropertyURLs] valueForKey:[[[asset valueForProperty:ALAssetPropertyURLs] allKeys] objectAtIndex:0]];
And get image from url like below.
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation *rep = [myasset defaultRepresentation];
#autoreleasepool {
CGImageRef iref = [rep fullScreenImage];
if (iref) {
UIImage *image = [UIImage imageWithCGImage:iref];
self.loadedImage = image;
dispatch_async(dispatch_get_main_queue(), ^{
//UIMethod trigger...
});
iref = nil;
}
}
};
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror)
{
NSLog(#"Can't get image - %#",[myerror localizedDescription]);
};
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:yourUrl
resultBlock:resultblock
failureBlock:failureblock];
UIImage *img = [UIImage imageWithCGImage:[[myAsset defaultRepresentation] fullResolutionImage]
Hope this helps

Get image name from UIImageWriteToSavedPhotosAlbum in ios [duplicate]

This question already has answers here:
Getting image name of iphone photo library
(2 answers)
Closed 9 years ago.
I've searched how to get the name of the saved image takes from the camera, but i didn't find something simple.
this is my code :
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if( [picker sourceType] == UIImagePickerControllerSourceTypeCamera){
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)image.imageOrientation completionBlock:^(NSURL *assetURL, NSError *error )
{
NSLog(#"IMAGE SAVED TO PHOTO ALBUM");
[library assetForURL:assetURL resultBlock:^(ALAsset *asset )
{
NSLog(#"we have our ALAsset!");
NSLog(#"%#", assetURL);
}
failureBlock:^(NSError *error )
{
NSLog(#"Error loading asset");
}];
}];
}
}
I you have the answer, i will happy to test it .
Thanks in advance.
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *resourceURL;
[picker dismissViewControllerAnimated:YES completion:nil];
UIImage *image =[[UIImage alloc] init];
image =[info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSURL *imagePath = [info objectForKey:#"UIImagePickerControllerReferenceURL"];
NSString *imageName = [imagePath lastPathComponent];
resourceURL = [info objectForKey:UIImagePickerControllerReferenceURL];
NSData *imageData;
NSString *extensionOFImage =[imageName substringFromIndex:[imageName rangeOfString:#"."].location+1 ];
if ([extensionOFImage isEqualToString:#"jpg"])
{
imageData = UIImagePNGRepresentation(image);
}
else
{
imageData = UIImageJPEGRepresentation(image, 1.0);
}
int imageSize=imageData.length/1024;
NSLog(#"imageSize--->%d", imageSize);
if (imageName!=nil) {
NSLog(#"imageName--->%#",imageName);
}
else
{
NSLog(#"no image name found");
}
}
If you are using ASSerts
-(void)assetPickerController:(WSAssetPickerController *)sender didFinishPickingMediaWithAssets:(NSArray *)assets
{
[self dismissViewControllerAnimated:YES completion:^{
if (assets.count < 1) return;
//self.pageControl.numberOfPages = assets.count;
int index = 0;
for (ALAsset *asset in assets) {
// NSString *imageName = [[asset defaultRepresentation] filename];
UIImage *image = [[UIImage alloc] initWithCGImage:asset.defaultRepresentation.fullScreenImage];
// (#"%#", [[asset defaultRepresentation] filename]);
NSData *imageData = UIImagePNGRepresentation(image);
int imageSize=imageData.length/1024;
(either)
NSURL *imagePath = [asset objectForKey:#"UIImagePickerControllerReferenceURL"];
// NSURL *imagePath = [NSURL URLWithString:[asset ob]];
NSString *imageName = [imagePath lastPathComponent];
(or)
NSLog(#"%#",[[asset defaultRepresentation] filename]);
index++;
}
}];
}
Try following code. I have used this in one of my previous project and its working for me :
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
_selectedImage = info[UIImagePickerControllerEditedImage];
self.photoView.image = _selectedImage;
NSURL *refURL = [info valueForKey:UIImagePickerControllerReferenceURL];
// define the block to call when we get the asset based on the url (below)
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *imageAsset)
{
ALAssetRepresentation *imageRep = [imageAsset defaultRepresentation];
NSLog(#"[imageRep filename] : %#", [imageRep filename]);
};
// get the asset library and fetch the asset based on the ref url (pass in block above)
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:refURL resultBlock:resultblock failureBlock:nil];
[picker dismissViewControllerAnimated:YES completion:NULL];
}

Received memory warning in create image file

I use this code get album pictures, and create file in the documents, but there will be Received memory warning, then crash。
Here is the code that I used. Can anyone tell me what did I do wrong?
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror){
NSLog(#"error occour =%#", [myerror localizedDescription]);
};
ALAssetsGroupEnumerationResultsBlock groupEnumerAtion = ^(ALAsset *result, NSUInteger index, BOOL *stop){
if (result!=NULL) {
//we can get all the things in the defaultRepresentation such as size info in UTI
}
//just fetching photos
if ([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) {
//copy image to the path:Documents/DMS/Photo
ALAssetRepresentation *rep = [result defaultRepresentation];
NSString *tt = [rep filename];
NSString *fullPath = [pathPhoto stringByAppendingFormat:#"/%#",tt];
if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath]){
UIImage *image = [[UIImage alloc]initWithCGImage:[rep fullScreenImage]];
NSData *imageData = UIImagePNGRepresentation(image);
[image release];
[[NSFileManager defaultManager] createFileAtPath:fullPath contents:imageData attributes:nil];
NSLog(#"Creat image file fullPath================%#",fullPath);
//imageData = nil;
[imageData release];
}else{
NSLog(#"---------------------the image is Exist");
}
}
};
ALAssetsLibraryGroupsEnumerationResultsBlock
libraryGroupsEnumeration = ^(ALAssetsGroup* group, BOOL* stop){
if (group == nil)
{
return;
}
if (group!=nil) {
[group enumerateAssetsUsingBlock:groupEnumerAtion];
}
NSLog(#"finish--------------------------------------------");
return;
};
ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
usingBlock:libraryGroupsEnumeration
failureBlock:failureblock];
[library release];
[pool release];
Since you say that you are using the code you posted inside of a loop, I suppose that what happens is that you app is being killed due to too many auto-released objects being allocated inside of the loop.
You could try using an autorelease pool:
for (...) {
#autoreleasepool {
<your code here>
}
}
so that the autorelease pool is cleaned up at each iteration (instead of growing all along the whole loop execution).
EDIT:
if ([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto])
{
ALAssetRepresentation *rep = [result defaultRepresentation];
CGImageRef iref = [rep fullScreenImage];
NSString *tt = [rep filename];
if (iref)
{
UIImage *image = [UIImage imageWithCGImage:iref];
if(!image)
{
NSLog(#"---------------------the imageData is nil");
}
else
{
NSData *imageData = UIImagePNGRepresentation(image);
NSString *fullPath = [pathPhoto stringByAppendingFormat:#"/%#.png",tt];
NSLog(#"fullPath================%#",fullPath);
if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath])
{
[[NSFileManager defaultManager] createFileAtPath:fullPath contents:imageData attributes:nil];
NSLog(#"Creat image file fullPath================%#",fullPath);
}
}
CGImageRelease(iref);
}
}

iOS UIImage returns null after downloading from NSURL

I have a loop that cycles through an array of urls which then saves images from those urls. This all works fine until the last image which returns a null image. I have verified that the url is correct and shows the image when i visit it in a web browser. I'm not sure where i'm going wrong here.
Here is the loop:
-(void) downloadImages {
NSString *filePath;
NSLog(#"About to start loop");
for (int i = 0; i < urls.count; i++) {
NSLog(#"Downloading: %#", [names objectAtIndex:i]);
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#", [urls objectAtIndex:i]]]]];
filePath = [NSString stringWithFormat:#"%#/images/%#.png", [[MakeAMemeIAPHelper sharedHelper] getDocumentsFolder], [names objectAtIndex:i]];
NSLog(#"Saving: %#", [names objectAtIndex:i]);
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)];
[imageData writeToFile:filePath atomically:YES];
progress += 0.1;
[self updateProgress];
}
NSLog(#"Done with loop");
}

Resources