Dans mon application, je dois charger de grandes images JPEG et les afficher dans une vue déroulante. Afin de garder l'interface user sensible, j'ai décidé de charger les images en arrière-plan, puis les afficher sur le fil principal. Afin de les charger complètement en arrière-plan, je force chaque image à être décompressée. J'utilisais ce code pour décompresser une image (notez que mon application est iOS 7 uniquement, donc je comprends que l'utilisation de ces methods sur un thread d'arrière-plan est OK):
+ (UIImage *)decompressedImageFromImage:(UIImage *)image { UIGraphicsBeginImageContextWithOptions(image.size, YES, 0); [image drawAtPoint:CGPointZero]; UIImage *decompressedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return decompressedImage; }
Cependant, j'avais encore de longs time de chargement, le bégaiement de l'interface user et beaucoup de pression de la memory. Je viens de find une autre 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; }
Ce code est mieux d'ordres de grandeur. L'image se charge presque immédiatement, il n'y a pas de bégaiement de l'interface user et l'utilisation de la memory a diminué.
Donc, ma question est double:
Je suppose que vous exécutez ceci sur un appareil Retina. Dans UIGraphicsBeginImageContextWithOptions
, vous avez demandé l'échelle par défaut, qui est l'échelle de l'écran principal, qui est 2. Cela signifie qu'elle génère un bitmap 4x aussi grand. Dans la deuxième fonction, vous dessinez à l'échelle 1x.
Essayez de passer une échelle de 1 à UIGraphicsBeginImageContextWithOptions
et de voir si vos performances sont similaires.