Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

defaultRepresentation fullScreenImage on ALAsset does not return full screen image

In my application I save images to an album as assets. I want also to retrieve them and display them in full screen. I use the following code :

ALAsset *lastPicture = [scrollArray objectAtIndex:iAsset]; 

ALAssetRepresentation *defaultRep = [lastPicture defaultRepresentation];

UIImage *image = [UIImage imageWithCGImage:[defaultRep fullScreenImage] 
                                          scale:[defaultRep scale] orientation:
    (UIImageOrientation)[defaultRep orientation]];

The problem is that the image returned is nil. I have read at the ALAssetRepresentation reference that when the image does not fit it is returned nil.

I put this image to an UIImageView which has the size of the iPad screen. I was wondering if you could help me with this issue?

Thank you in advance.

like image 463
user1480179 Avatar asked Jul 09 '12 09:07

user1480179


1 Answers

I'm not a fan of fullScreenImage or fullResolutionImage. I found that when you do this on multiple assets in a queue, even if you release the UIImage immediately, memory usage will increase dramatically while it shouldn't. Also when using fullScreenImage or fullResolutionImage, the UIImage returned is still compressed, meaning that it will be decompressed before being drawn for the first time, thus on the main thread which will block your UI.

I prefer to use this method.

-(UIImage *)fullSizeImageForAssetRepresentation:(ALAssetRepresentation *)assetRepresentation
{
    UIImage *result = nil;
    NSData *data = nil;

    uint8_t *buffer = (uint8_t *)malloc(sizeof(uint8_t)*[assetRepresentation size]);
    if (buffer != NULL) {
        NSError *error = nil;
        NSUInteger bytesRead = [assetRepresentation getBytes:buffer fromOffset:0 length:[assetRepresentation size] error:&error];
        data = [NSData dataWithBytes:buffer length:bytesRead];

        free(buffer);
    }

    if ([data length])
    {
        CGImageSourceRef sourceRef = CGImageSourceCreateWithData((__bridge CFDataRef)data, nil);

        NSMutableDictionary *options = [NSMutableDictionary dictionary];

        [options setObject:(id)kCFBooleanTrue forKey:(id)kCGImageSourceShouldAllowFloat];
        [options setObject:(id)kCFBooleanTrue forKey:(id)kCGImageSourceCreateThumbnailFromImageAlways];
        [options setObject:(id)[NSNumber numberWithFloat:640.0f] forKey:(id)kCGImageSourceThumbnailMaxPixelSize];
        //[options setObject:(id)kCFBooleanTrue forKey:(id)kCGImageSourceCreateThumbnailWithTransform];

        CGImageRef imageRef = CGImageSourceCreateThumbnailAtIndex(sourceRef, 0, (__bridge CFDictionaryRef)options);

        if (imageRef) {
            result = [UIImage imageWithCGImage:imageRef scale:[assetRepresentation scale] orientation:(UIImageOrientation)[assetRepresentation orientation]];
            CGImageRelease(imageRef);
        }

        if (sourceRef)
            CFRelease(sourceRef);
    }

    return result;
}

You can use it like this:

// Get the full image in a background thread
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

    UIImage* image = [self fullSizeImageForAssetRepresentation:asset.defaultRepresentation];
    dispatch_async(dispatch_get_main_queue(), ^{

    // Do something with the UIImage
    });
});
like image 179
David Avatar answered Oct 15 '22 00:10

David