Resizing images with CGImageCreate to reduce memory usage

Sometimes images are very large (downloaded from the Internet), so I need to resize them, but I don’t want to cause a memory problem, which means I don’t want to load all the image data into memory and resize it within the memory.

I am exploring the servile ways of resizing an image, tracking their use in memory. In particular CGContextDrawImage, CGImageSourceCreateThumbnailAtIndexand CGImageCreatewith CGDataProviderRef.

Now I am facing some problems when using CGImageCreatewith CGDataProviderRef, and my code is as follows:

//This method read the data from filePath, resize the image and write the resized data to the destPath
- (void)resizeImageFileUsingCGImageCreate:(NSString*)filePath toDestPath:(NSString*)destPath {

    CGFloat factor = 0.2;
    CGSize originalSize = [self sizeOfImageAtURL:[[NSURL alloc] initFileURLWithPath:filePath]];
    CGSize destSize = CGSizeMake((NSUInteger)(originalSize.width * factor), (NSUInteger)(originalSize.height * factor));



    UIImage *srcImage = [UIImage imageWithContentsOfFile:filePath];
    CGImageRef srcImgRef = srcImage.CGImage;
    NSData *data = [NSData dataWithContentsOfFile:filePath];
    CFDataRef cfData = (__bridge_retained CFDataRef)data;
    CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(cfData);
    CFRelease(cfData);

    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(srcImgRef);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGImageRef imageRef = CGImageCreate(destSize.width, destSize.height, 8, 32, 4 * destSize.width, colorSpace, bitmapInfo, dataProvider, NULL, NO, 0);

    CGDataProviderRelease(dataProvider);
    CGColorSpaceRelease(colorSpace);
    UIImage *image = nil;
    if (imageRef != NULL) {
        image = [[UIImage alloc] initWithCGImage:imageRef];
        CGImageRelease(imageRef);
        //Why UIImageJPEGRepresentation(image, 0.5) returns nil?
        [UIImageJPEGRepresentation(image, 0.5) writeToFile:destPath atomically:YES];


    }


}

UIImageJPEGRepresentation(image, 0.5) nil, . CGImageCreate CGDataProviderRef? !

+4
2

, , , , : ImageIO.

#import <ImageIO/ImageIO.h>

, (imageSource - NSURL; scale, maxw maxh , ):

CGImageSourceRef src = 
    CGImageSourceCreateWithURL((__bridge CFURLRef)imageSource, nil);
NSDictionary* d = @{
    (id)kCGImageSourceShouldAllowFloat: (id)kCFBooleanTrue,
    (id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue,
    (id)kCGImageSourceCreateThumbnailFromImageAlways: (id)kCFBooleanTrue,
    (id)kCGImageSourceThumbnailMaxPixelSize: @((int)(maxw > maxh ? maxw : maxh))
};
CGImageRef imref = 
    CGImageSourceCreateThumbnailAtIndex(src, 0, (__bridge CFDictionaryRef)d);
if (NULL != src)
    CFRelease(src);
UIImage* im = 
    [UIImage imageWithCGImage:imref scale:scale orientation:UIImageOrientationUp];
if (NULL != imref)
    CFRelease(imref);

: ; . UIImage, .

NSData , , :

src = CGImageSourceCreateWithData((__bridge CFDataRef)imageSource, nil);

, , , , .

+2

:

    [UIImageJPEGRepresentation(image, 0.5) writeToFile:destPath atomically:YES];

:

NSData *imageData = UIImageJPEGRepresentation(image, 0.5);
if(imageData) 
{
    NSError *error = nil;
    BOOL success = [imageData writeToFile:destPath options:NSDataWritingAtomic error:&error];
    if(NO == success)
    {
        NSLog(@"couldn't write image data to file %@ because of error %@", destPath, error)
    }
}

NSData, , .

0

Source: https://habr.com/ru/post/1529924/


All Articles