Image size transformation is a common function in App, especially for projects with frequent image processing, so the performance of several commonly used image processing methods was tested to find the optimal way to deal with image size in space and time.

Our test was carried out using XCTest. The main measurement indicators were time and space, namely time and memory.

Image compression method 1:

func normalizedImageScale(toMaxLength maxLength:CGFloat) -> UIImage {
        
        
        let realSize = CGSize.init(width: Int(size.width * scale), height: Int(size.height * scale))
        let fMaxLength = CGFloat(maxLength)
        var targetSize : CGSize
        if realSize.width < fMaxLength && realSize.height < fMaxLength {
            targetSize = size
        } else{
            if realSize.width > realSize.height {
                targetSize = CGSize.init(width: Int(maxLength), height: Int(realSize.height / (realSize.width / maxLength)))
            } else{
                targetSize = CGSize.init(width: Int(realSize.width / (realSize.height / maxLength)), height: Int(maxLength))
            }
        }
        UIGraphicsBeginImageContext(targetSize)
        draw(in: CGRect.init(origin: .zero, size:targetSize))
        let normalizedImage = UIGraphicsGetImageFromCurrentImageContext(a)UIGraphicsEndImageContext(a)return normalizedImage ?? UIImage()}Copy the code

Image compression method two:

func resizeImage(with image: UIImage.targetSize: CGSize) -> UIImage {
  	let render = UIGraphicsImageRenderer(bounds: CGRect(origin: .zero, size: targetSize))
  	let result = render.image { (context) in
                    image.draw(in: CGRect(origin: .zero, size: CGSize(width: 480, height: 640)))}return result
}
Copy the code

Image compression method three:

#import "UIImage+Resize.h"

- (UIImage *)resizedImage:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)quality {
    BOOL drawTransposed;
    switch ( self.imageOrientation )
    {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
	    drawTransposed = YES;
	    break;
        default:
	    drawTransposed = NO;
    }
        
    CGAffineTransform transform = [self transformForOrientation:newSize];
    
  	CGFloat scale = MAX(1.0f, self.scale);
    CGRect newRect = CGRectIntegral(CGRectMake(0.0, newSize.width*scale, newSize.height*scale));
    CGRect transposedRect = CGRectMake(0.0, newRect.size.height, newRect.size.width);
    CGImageRef imageRef = self.CGImage;
    
    // Fix for a colorspace / transparency issue that affects some types of 
    // images. See here: http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/comment-page-2/#comment-39951
        
	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(a);CGContextRef bitmap = CGBitmapContextCreate(
                                                NULL,
                                                newRect.size.width,
                                                newRect.size.height,
                                                8./* bits per channel */
                                                (newRect.size.width * 4), /* 4 channels per pixel * numPixels/row */
                                                colorSpace,
                                                kCGImageAlphaPremultipliedLast
                                                );
    CGColorSpaceRelease(colorSpace);
	
    // Rotate and/or flip the image if required by its orientation
    CGContextConcatCTM(bitmap, transform);
    
    // Set the quality level to use when rescaling
    CGContextSetInterpolationQuality(bitmap, quality);
    
    // Draw into the context; this scales the image
    CGContextDrawImage(bitmap, drawTransposed ? transposedRect : newRect, imageRef);
    
    // Get the resized image from the context and a UIImage
    CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef scale:self.scale orientation:UIImageOrientationUp];
    
    // Clean up
    CGContextRelease(bitmap);
    CGImageRelease(newImageRef);
    
    return newImage;
}
Copy the code

Test an image (2400*3200, 1.5m), compress 100 times average:

plan time memory
Plan a 23.3 ms 13.8 k.
Scheme 2 46.2 ms 10.7 k.
Plan 3 19.2 ms 9.42 k.

Test 100 images, compress 5 times average value:

plan time memory
Plan a 2.86 s 573k
Scheme 2 5.38 s 362k
Plan 3 2.44 s 593k

The above test results show that:

When the number of images is small, scheme 3 is slightly better than scheme 1, both better than scheme 2. When processing a large number of images, scheme 2 has a lower memory footprint, but it takes about twice as long as the other two schemes.

Note: the above tests were run on the iPhone11 simulator.

In addition, there are other Image compression schemes, which are not listed here. See article: Image Resizing Techniques