In my app I need to load large JPEG images and display them in a scroll view. In order to keep the UI responsive, I decided to load the images in the background, then display them on the main thread. In order to fully load them in the background, I force each image to be decompressed. I was using this code to decompress an image (note that my app is iOS 7 only, so I understand that using these methods on a background thread is OK):
+ (UIImage *)decompressedImageFromImage:(UIImage *)image {
    UIGraphicsBeginImageContextWithOptions(image.size, YES, 0);
    [image drawAtPoint:CGPointZero];
    UIImage *decompressedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return decompressedImage;
}
However, I still had long load times, UI stutter, and a lot of memory pressure. I just found another solution:
+ (UIImage *)decodedImageWithImage:(UIImage *)image {
    CGImageRef imageRef = image.CGImage;
    // System only supports RGB, set explicitly and prevent context error
    // if the downloaded image is not the supported format
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL,
                                                 CGImageGetWidth(imageRef),
                                                 CGImageGetHeight(imageRef),
                                                 8,
                                                 // width * 4 will be enough because are in ARGB format, don't read from the image
                                                 CGImageGetWidth(imageRef) * 4,
                                                 colorSpace,
                                                 // kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little
                                                 // makes system don't need to do extra conversion when displayed.
                                                 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);
    CGColorSpaceRelease(colorSpace);
    if ( ! context) {
        return nil;
    }
    CGRect rect = (CGRect){CGPointZero, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)};
    CGContextDrawImage(context, rect, imageRef);
    CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);
    CGContextRelease(context);
    UIImage *decompressedImage = [[UIImage alloc] initWithCGImage:decompressedImageRef];
    CGImageRelease(decompressedImageRef);
    return decompressedImage;
}
This code is orders of magnitude better. The image loads almost immediately, there is no UI stutter, and the memory usage has gone way down.
So my question is two-fold:
An object that manages image data in your app.
UIImageView *imageview = [[UIImageView alloc] initWithFrame:CGRectMake(10.0, 20.0, 0.0, 0.0)]; UIImage *myimg = [UIImage imageNamed:@"A1. jpg"]; imageview. image=myimg; [imageview sizeToFit]; And don't forget to add image view to view hierarchy.
You can display an image in a SwiftUI view by using the Image view. First you need to add the image to a new image set in your Assets. xcassets file in the Xcode project navigator.
I assume that you're running this on a Retina device. In UIGraphicsBeginImageContextWithOptions, you asked for the default scale, which is the scale of the main screen, which is 2. This means that it's generating a bitmap 4x as large. In the second function, you're drawing at 1x scale.
Try passing a scale of 1 to UIGraphicsBeginImageContextWithOptions and see if your performance is similar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With