4

I am using ChuteSDK to import multiple images from photo library something like this:

-(void)doneSelected{
NSMutableArray *returnArray = [NSMutableArray array];
[self showHUD];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(void){
    for(id object in [self selectedAssets]){
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        if([object isKindOfClass:[GCAsset class]]){
            ALAsset *asset = [object alAsset];
            NSMutableDictionary* temp = [NSMutableDictionary dictionary];
            [temp setObject:[[asset defaultRepresentation] UTI] forKey:UIImagePickerControllerMediaType];

            [temp setObject:[UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage] scale:1 orientation:(UIImageOrientation)[[asset defaultRepresentation] orientation]] forKey:UIImagePickerControllerOriginalImage];

            [temp setObject:[[asset defaultRepresentation] url] forKey:UIImagePickerControllerReferenceURL];
            [returnArray addObject:temp];
        }
        [pool release];
    }
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        if(delegate && [delegate respondsToSelector:@selector(PhotoPickerPlusController:didFinishPickingArrayOfMediaWithInfo:)])
            [delegate PhotoPickerPlusController:[self P3] didFinishPickingArrayOfMediaWithInfo:returnArray];
        [self hideHUD];
    });
});
}

But fullScreenImage is giving me a scaled down version of the original image and if I use fullResolutionImage it is causing low memory warning issue due to which the app is crashing.

How can I get the image with original resolution without causing memory problems.

P.S: I'm not using ARC in my project.

Ankur Arya
  • 4,693
  • 5
  • 29
  • 50
  • What if you move the image setting code out of the async block. When you need to show the images, use the AssetURL to get to the image. In other words, Dynamically load your images as they are about to come into the visible frame, rather than allocating when they are not needed, as they are large files. – some_id Aug 08 '13 at 06:31
  • I am not able to get the original resolution image from AssetURL, what's the way to do it? – Ankur Arya Aug 08 '13 at 06:40
  • Not really sure why you are storing a copy of the image in a dictionary when you already have a reference to the ALAsset and thus the image. So this line [temp setObject:[UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage] scale:1 orientation:(UIImageOrientation)[[asset defaultRepresentation] orientation]] forKey:UIImagePickerControllerOriginalImage]; should just be [UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage] scale:1 orientation:(UIImageOrientation)[[asset defaultRepresentation] orientation]]; when assigning to the visible image. – some_id Aug 08 '13 at 07:18
  • You are currently storing an actual image in the nsmutabledictionary. – some_id Aug 08 '13 at 07:19
  • I want to use `fullResolutionImage ` instead of `fullScreenImage ` so that I can upload the full resolution image to server but this gives me memory warning. Other option is (as you mentioned) just store the Asset URL and get original image from that url while uploading but the problem is I don't know how to do that. – Ankur Arya Aug 08 '13 at 07:33
  • Check this - http://stackoverflow.com/questions/3837115/display-image-from-url-retrieved-from-alasset-in-iphone let me know if it helped. cheers – some_id Aug 08 '13 at 07:41
  • It would be nice of you to accept a correct answer to your question by clicking the gray checkmark next to it. – Rajesh Feb 11 '14 at 12:26

2 Answers2

2

'returnArray' variable you declared is outside the autorelease pool block. Now you are adding your image to a dictionary 'temp' which is inside auto release pool but ultimately you are adding this 'temp' to 'returnArray' and hence its retain count increased which is causing a leak actually.

Even do keep in mind one more thing while working with images. When you are using an image it doesn't take the memory what it shows as file size as many would be expecting (ie., some thing less than 3MB for a 2048 x 1536 ) . Instead it is actually loaded in raw format taking memory based on a calculation as follows:

width x height x n bytes where n is number of bits being taken to represent colors per pixel mostly it is 4.

so for same 2048 x 1536 image it is going to take 12MB.

So now check what is the original resolution of the image you are talking about and calculate how much MB its gonna take, and change your code as per that.

Rajesh
  • 850
  • 9
  • 18
0

You are decompressing all the images at once. Wait until you absolutely need them.

Walt Sellers
  • 3,806
  • 30
  • 35