loading images from disk in iPhone app is slow

前端 未结 3 1821
别跟我提以往
别跟我提以往 2020-12-23 12:35

In my iPhone app, I am using the iPhone\'s camera to take a photo and save it do disk (the application\'s documents folder). This is how i save it:

[UIImageJ         


        
相关标签:
3条回答
  • 2020-12-23 13:22

    This is the faster way I know. You'll need to import #import <ImageIO/ImageIO.h>

    I use this code to download and compress images during a scroll, inside a scrollview and you barely notice the delay.

    CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef)mutableData, NULL);
    CFDictionaryRef options = (CFDictionaryRef)[[NSDictionary alloc] initWithObjectsAndKeys:(id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform, (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageIfAbsent, (id)[NSNumber numberWithDouble:200.0], (id)kCGImageSourceThumbnailMaxPixelSize, nil];
    CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options);
    
    UIImage *image = [[UIImage alloc] initWithCGImage:thumbnail];
    // Cache
    NSString *fileName = @"fileName.jpg";
    NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"thumbnail"];
    path = [path stringByAppendingPathComponent:fileName];
    if ([UIImagePNGRepresentation(image) writeToFile:path atomically:YES]) {
        // Success
    }
    
    0 讨论(0)
  • 2020-12-23 13:22

    I face a very similar issue where I had to load hundreds of images from the directory. My performance was quite slow if I used UIImage(contentsOfFile:) method. The below method increased my performance to 70 %.

    class ImageThumbnailGenerator: ThumbnailGenerator { private let url: URL

        init(url: URL) {
           self.url = url
        }
    
    func generate(size: CGSize) -> UIImage? {
        guard let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil) else {
            return nil
        }
    
        let options: [NSString: Any] = [
            kCGImageSourceThumbnailMaxPixelSize: Double(max(size.width, size.height) * UIScreen.main.scale),
            kCGImageSourceCreateThumbnailFromImageIfAbsent: true
        ]
    
        return CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options as NSDictionary).flatMap { UIImage(cgImage: $0) }
     }
    }
    
    0 讨论(0)
  • 2020-12-23 13:41

    +imageWithContentsOfFile: is synchronous, so the UI on your main thread is being blocked by the image loading from disk operation and causing the choppiness. The solution is to use a method that loads the file asynchronously from disk. You could also do this in a background thread. This can be done easily by wrapping the +imageWithContentsOfFile: in dispatch_async(), then a nested dispatch_async() on the main queue that wraps -setBackgroundImage: since UIKit methods need to be run on the main thread. If you want the image to appear immediately after the view loads, you'll need to pre-cache the image from disk so it's in-memory immediately when the view appears.

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
    
        UIImage *image = [UIImage imageWithContentsOfFile:frontPath];
    
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.frontButton setBackgroundImage:image forState:UIControlStateNormal];
        });
    
    });
    

    As an aside, if the button image happens a gradient, consider using the following properties to ensure the image file loaded from disk is tiny:

    - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets
    

    or (deprecated, only use if you need to support iOS 4.x):

    - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight
    
    0 讨论(0)
提交回复
热议问题