Reputation: 34810
I am building a share extension and I need to scale large photos to a smaller size before uploading in my share extension.
I'm using this code from How to resize an UIImage while maintaining its Aspect Ratio:
- (UIImage*) scaleImage:(UIImage*)image toSize:(CGSize)newSize {
CGSize scaledSize = newSize;
float scaleFactor = 1.0;
if( image.size.width > image.size.height ) {
scaleFactor = image.size.width / image.size.height;
scaledSize.width = newSize.width;
scaledSize.height = newSize.height / scaleFactor;
}
else {
scaleFactor = image.size.height / image.size.width;
scaledSize.height = newSize.height;
scaledSize.width = newSize.width / scaleFactor;
}
UIGraphicsBeginImageContextWithOptions( scaledSize, NO, 0.0 );
CGRect scaledImageRect = CGRectMake( 0.0, 0.0, scaledSize.width, scaledSize.height );
[image drawInRect:scaledImageRect];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}
However, when I'm trying to scale down a large image from my photos library (5415x3610 in this case, shot with a DSLR) it crashes due to memory pressure. While it seems like a corner case, my app depends highly on iOS Share Extension to share photos from non-iPhone sources like a high-resolution photo from a camera.
Obviously, uploading a 20MP/8MB photo without scaling down is not an option. How can I scale it down with less memory use?
Upvotes: 3
Views: 1277
Reputation: 1403
Had the same problem like you. The scale down operation was increasing my memory usage by +800MB and at times the app crashed because of memory usage. What worked for me was replacing UIGraphicsBeginImageContextWithOptions
with the new ios 10 UIGraphicsImageRendererFormat
. Here's my swift code of performing image scaling:
extension UIImage {
func scaled(to size: CGSize) -> UIImage {
let format = UIGraphicsImageRendererFormat()
format.scale = scale
let renderer = UIGraphicsImageRenderer(size: size, format: format)
return renderer.image { (_) in
draw(in: CGRect(origin: .zero, size: size))
}
}
}
Upvotes: 3
Reputation: 362
It seems like your image and scaledImage are in memory at once, which both images could be using to much. You could try to release your image before creating your scaledImage:
//code
[image drawInRect:scaledImageRect];
image = nil;
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//code
Upvotes: 0