Anti Alias, UIImage et Performance

J'ai un UIImage chargé dans un UIImageView . Le UIImage est plus grand que le UIImageView et il a été réduit pour s'adapter. Évidemment, l' UIImage présente des bords irréguliers.

Quel est le meilleur moyen d'anti-alias cette image en ce qui concerne la performance?

J'ai vu cette méthode en utilisant drawInRect mais j'ai aussi lu que drawInRect ne donne pas les meilleures performances .

J'ai lu plusieurs articles différents et j'ai essayé quelques methods moi-même. Mais après avoir lu quelques messages sur les différences de performance entre l'utilisation de UIViews et Core Graphics, je me demandais quelle méthode pour l'anti-aliasing une image donne la meilleure performance?

Recherchez la list des filters d'image de base disponibles. Plus précisément, la Transformation Scale Lanczos disponible via CILanczosScaleTransform semble être exactement ce dont vous avez besoin. Il devrait être disponible sur toutes les versions iOS> = 6.0.

Généralement, l'utilisation de filters Image de base sera plus performante que le recours fréquent à Core Graphics. Cependant, je vous invite à vérifier les résultats ainsi que les performances dans votre cas spécifique.

La meilleure solution est toujours d'avoir la bonne taille d'image dans votre UIImageView . Cependant, si vous ne pouvez pas avoir la taille d'image correcte et que vous devez la resize, une autre bonne solution consiste à utiliser CoreGraphics pour effectuer une opération d'échelle d'image en dehors du thread principal.

Depuis le SDK 4.0, les opérations CoreGraphics sont sans danger pour les threads , vous pouvez donc placer tous les éléments de redimensionnement dans une queue en arrière-plan et gérer le redimensionnement. Une fois le redimensionnement terminé, vous devez affecter l'image recadrée dans votre UIImageView dans le thread principal, car toutes les UIKit doivent être effectuées dans ce thread. Avec cette approche, vous n'allez pas bloquer le thread principal chaque fois que vous redimensionnez les images.

Une fois que vous avez fait cela, vous pouvez également mettre en cache les résultats de recadrage afin d'éviter un calcul de recadrage répétitif (c.-à-d. Chaque fois que vous faites défiler dans le même UITableViewCell ) et améliorer les performances.

Vous pouvez implémenter ceci comme une catégorie UIImage , prenez mon code comme exemple:

 - (void)resizeImageWithSize:(CGSize)size cacheKey:(NSSsortingng *)cacheKey completionBlock:(void (^)(UIImage *croppedImage))completionBlock { dispatch_async([[self class] sharedBackgroundQueue], ^{ // Check if we have the image cached UIImage *resizedImage = [[[self class] resizedImageCache] objectForKey:cacheKey]; if (nil == resizedImage) { // If not, resize and cache it @autoreleasepool { resizedImage = [self resizeImageWithSize:size]; [[[self class] resizedImageCache] setObject:resizedImage forKey:cacheKey]; } } dispatch_async(dispatch_get_main_queue(), ^{ completionBlock(resizedImage); }); }); } 

Ensuite, l' resizeImageWithSize: méthode resizeImageWithSize: est celle où toutes les tâches CoreGraphics se produisent. Vous pouvez find intéressant la bibliothèque FXImageView par Nick Lockwood, qui utilise la même approche: UIImageView catégorie, dispose d'un cache de redimensionnement et utilise un thread d'arrière-plan pour faire les choses Core Graphics.

Puisque vous avez posé des questions sur Swift dans les commentaires:

Alamofire intègre tout cela, y compris une couche de caching automatique. Si vous n'utilisez pas cela pour les requests de réseau, c'est à tout le less un bon exemple de travail.

Exemple:

 // Note: this seamlessly handles both scaling AND caching the scaled image let filter = AspectScaledToFillSizeFilter(size: imageView.frame) imageView.af_setImage(withURL: url, filter: filter) 

Assurez-vous imageView.frame que le imageView.frame est défini au préalable (par exemple appelez layoutIfNeeded() premier pour autolayout), sinon il s'affirmera.