2013-07-30 4 views
0

Je dois séparer 50 images carrées (600px x 600px) en 9 parties carrées de taille égale (200x200). Pour obtenir chaque partie j'utilise la méthode:CoreGraphics: Partition d'image de masse

-(UIImage *)getSubImageFrom:(UIImage *)img WithRect:(CGRect)rect 
{ 
UIGraphicsBeginImageContext(rect.size); 
CGContextRef context = UIGraphicsGetCurrentContext(); 

// translated rectangle for drawing sub image 
CGRect drawRect = CGRectMake(-rect.origin.x, -rect.origin.y, img.size.width, img.size.height); 

// clip to the bounds of the image context 
// not strictly necessary as it will get clipped anyway? 
CGContextClipToRect(context, CGRectMake(0, 0, rect.size.width, rect.size.height)); 

// draw image 
[img drawInRect:drawRect]; 

// grab image 
UIImage* subImage = UIGraphicsGetImageFromCurrentImageContext(); 

CGContextRelease(context); 

return subImage; 
} 

Et c'était assez rapide pour moi ... depuis aujourd'hui. J'avais l'habitude de charger des images en utilisant la méthode [UIImage imageNamed:]. Cette méthode ne libère PAS la mémoire jusqu'à ce que l'application obtienne un avertissement de mémoire ... Ce qui était inacceptable pour moi. J'ai donc commencé à utiliser [UIImage imageWithContentsOfFile]. Problèmes avec l'allocation de mémoire ont disparu ... malheureusement ma méthode de culture (- (UIImage *) getSubImageFrom: (UIImage *) img WithRect: (CGRect) rect) a commencé à fonctionner 20 fois plus lent! C'est maintenant plusieurs heures depuis que j'ai commencé à chercher une solution ... sans résultat. J'espère que tu peux m'aider.

Meilleures salutations!

PS. J'ai essayé d'utiliser des conseils de cette question CGContextDrawImage is EXTREMELY slow after large UIImage drawn into it, sans aucun résultat.

Répondre

0

C'est ce que nous appelons un «compromis». Vous vous plaignez que +[UIImage imageNamed:] rend les choses plus rapides mais utilise plus de mémoire, et que +[UIImage imageWithContentsOfFile:] est lent mais n'utilise pas autant de mémoire. La raison pour laquelle ce dernier est lent est que chaque fois que vous appelez +[UIImage imageWithContentsOfFile:] il doit lire et décoder l'image de "disque" et cela prend du temps (une quantité non négligeable de temps, comme vous l'avez appris). Lorsque vous utilisez +[UIImage imageNamed:], il est lu et décodé une fois, puis le résultat de l'opération de lecture/décodage est conservé en mémoire jusqu'à ce qu'un avertissement de mémoire arrive. Cela signifie que les accès suivants de cette image (avant un avertissement de mémoire) seront rapides.

Il semble qu'une bonne approche serait pour vous de mettre en cache les images dans un cache dont vous pouvez contrôler la durée de vie. NSCache serait le choix évident, car il est également accroché dans les crochets de la mémoire du système, mais vous pouvez explicitement supprimer les choses plus tôt en utilisant -removeObjectForKey:

Une autre approche pourrait être de créer vos sous-images une fois et de les écrire sur le disque (voir NSCachesDirectory pour un bon endroit pour mettre de telles choses). Cela éliminera le besoin de faire cette opération (relativement coûteuse) plus d'une fois, et les images plus petites (en supposant que vous n'en ayez pas besoin) peuvent être plus rapides à charger à partir du disque que les images plus grandes.

Pour jouer le défenseur du diable pendant une minute: Si UIImage fait ce qu'il faut quand un avertissement de mémoire arrive, pourquoi vous souciez-vous qu'il utilise la mémoire? Cette utilisation de la mémoire provoque-t-elle réellement la mort de votre application? (Je sais par expérience que les avertissements de mémoire ne sont pas imbriqués - c'est-à-dire que vous n'avez pas forcément assez de temps pour réduire votre consommation avant que votre processus ne soit tué - mais avez-vous réellement ce problème? les efforts visant à réduire la consommation de mémoire peuvent être considérés comme une optimisation prématurée?