Il est presque impossible de trouver une application Android moderne qui n’affiche pas d’images, qu’il s’agisse de photos de produits, d’avatars ou d’éléments d’interface utilisateur décoratifs. Aussi courante soit-elle, le chargement d’images peut être une tâche étonnamment complexe : vous avez besoin d’une récupération asynchrone, de la mise en cache, de l’affichage d’espaces réservés, de la gestion des erreurs et parfois d’animations ou de transformations. En tant qu’entreprise de développement d’applications Android avec plus de 16 ans d’expérience, nous le savons de première main. Heureusement, plusieurs bibliothèques bien établies — Picasso, Glide et Fresco — gèrent ces détails avec aisance.
En 2025, ces trois ressources restent les principaux concurrents pour le chargement d’images Android, chacune avec ses avantages uniques. Ci-dessous, nous comparerons leurs stratégies de mise en cache, leurs API de transformation, leurs capacités d’animation et leurs fonctionnalités « sympas », afin de vous aider à choisir la meilleure solution pour votre projet.
Présentation des bibliothèques
Picasso
- Origines : Créé par Square, connu pour OkHttp, Retrofit et LeakCanary
- Philosophie : Approche minimaliste, empreinte plus petite (ajoute ~121 Ko, ~849 méthodes)
- Avantages : API simple, configuration rapide, excellent pour les cas d’utilisation basiques
- Inconvénients : Fonctionnalités avancées limitées prêtes à l’emploi ; vous pourriez avoir recours à des extensions tierces pour des transformations plus complexes ou un contrôle d’animation
Glide
- Origines : Développé par BumpTech (maintenant intégré à l’écosystème open-source de Google)
- Philosophie : Fonctionnalités robustes et transformations flexibles
- Empreinte : Plus importante (~440 Ko, ~2678 méthodes)
- Avantages : Système de mise en cache puissant, prise en charge native des GIF, transformations avancées et animations de fondu croisé faciles
- Inconvénients : Taille de bibliothèque et nombre de méthodes plus importants
Fresco
- Origines : Créé par Facebook
- Philosophie : Gestion de la mémoire performante et efficace, en particulier sur les anciennes versions d’Android
- Détail d’implémentation : Utilise sa propre classe
SimpleDraweeViewau lieu deImageView - Avantages : Gère les images en dehors du tas Java traditionnel, réduisant ainsi les
OutOfMemoryError. Idéal pour les interfaces utilisateur complexes ou les appareils plus anciens - Inconvénients : Architecture plus spécialisée ; les transformations peuvent être plus complexes
Mise en cache et gestion de la mémoire
Les images peuvent figurer parmi les plus gros éléments d’une application Android, exerçant une pression sur la bande passante réseau et la mémoire de l’appareil. Une mise en cache efficace garantit que les images fréquemment demandées se chargent instantanément, éliminant les téléchargements inutiles et réduisant l’utilisation des données mobiles. Une bonne gestion de la mémoire évite également les ralentissements ou les plantages dus à un manque de RAM, en particulier sur les appareils d’entrée ou de gamme ou plus anciens.
Picasso
- Caches par défaut :
- Mémoire : Cache LRU (~15% de la RAM disponible de l’application).
- Disque : 5–50 Mo (ajusté automatiquement en fonction du stockage).
- Paramètres :
memoryPolicy()etnetworkPolicy()vous permettent de contrôler le comportement de mise en cache.
Par exemple, une telle requête forcera Picasso à télécharger constamment des images depuis le réseau :
Picasso.get()
.load(imageUrl)
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
.into(testImageView)
Glide
- 4 niveaux de cache :
- Ressources actives (affichées actuellement)
- Cache mémoire (décodées en RAM)
- Cache disque de ressources (converties/décodées sur disque)
- Cache disque de données (données d’image brutes sur disque)
- DiskCacheStrategy :
ALL, DATA, RESOURCE, NONE. Vous pouvez ignorer le cache mémoire avecskipMemoryCache(true). - Clés personnalisées : Utilisez
signature()pour différencier plusieurs versions de la même image (par exemple, pour différentes transformations).
Fresco
- 3 niveaux de cache :
- Bitmap (décodé, prêt à être affiché)
- Mémoire encodée (image compressée originale en mémoire)
- Disque (image compressée originale sur le stockage local)
- Gestion : Classe
ImagePipelinepour vérifier, évincer ou effacer les caches. Exemple :
val imagePipeline = Fresco.getImagePipeline()
imagePipeline.evictFromMemoryCache(uri)
imagePipeline.evictFromDiskCache(uri)
imagePipeline.clearMemoryCaches()
imagePipeline.clearDiskCaches()
- Caches d’images de petite taille : Maintenez éventuellement un cache de miniatures séparé, améliorant les performances.
Transformations et traitement avancé des images
L’un des principaux avantages offerts par les chargeurs d’images est la capacité de traiter les images avant qu’elles n’apparaissent à l’écran. Cela permet aux développeurs d’unifier la marque, d’économiser de la bande passante grâce à l’optimisation à la volée ou d’appliquer des effets créatifs qui augmentent l’engagement de l’utilisateur. Sans transformations intégrées, les équipes devraient écrire une logique personnalisée complexe, ce que ces bibliothèques gèrent nativement, économisant ainsi du temps et des efforts.
Picasso
- Intégré :
resize(),centerCrop(),centerInside(),rotate(). - Personnalisé : Héritez de
Transformation, définissez votre logique danstransform()et unekey()unique. - Extensions tierces : par exemple, la bibliothèque Wasabeef pour les transformations de forme, les flous et les filtres.
Exemple : Transformation circulaire
class CircleTransformation : Transformation {
override fun transform(source: Bitmap): Bitmap {
val paint = Paint(Paint.ANTI_ALIAS_FLAG)
paint.shader = BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
val output = Bitmap.createBitmap(source.width, source.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
canvas.drawCircle(source.width / 2f, source.height / 2f, source.width / 2f, paint)
if (source != output) source.recycle()
return output
}
override fun key() = "circle"
}
Glide
- Intégré :
resize(),centerCrop(),circleCrop(),roundedCorners(), etc. - Personnalisé : Étendez BitmapTransformation, DrawableTransformation, etc. Vous devez redéfinir
equals(),hashCode(),transform()etupdateDiskCacheKey(). - Tiers : De même, les bibliothèques Wasabeef ou Werbhelius pour plus de filtres.
Exemple : Transformation en niveaux de gris
class GreyscaleTransformation : BitmapTransformation() {
override fun transform(pool: BitmapPool, source: Bitmap, outWidth: Int, outHeight: Int): Bitmap {
val bitmap = Bitmap.createBitmap(source.width, source.height, Bitmap.Config.ARGB_8888)
val paint = Paint()
val greyMatrix = ColorMatrix().apply { setSaturation(0f) }
paint.colorFilter = ColorMatrixColorFilter(greyMatrix)
Canvas(bitmap).drawBitmap(source, 0f, 0f, paint)
return bitmap
}
// equals(), hashCode(), updateDiskCacheKey() ...
}
Fresco
- XML vs. Code : De nombreuses transformations peuvent être spécifiées directement dans le XML de mise en page via des attributs.
- Postprocessor : Étendez
BasePostprocessorpour définir des transformations personnalisées (similaire à une approche « dessiner sur bitmap »).
Exemple : Arrondir facilement les coins avec :
val roundingParams = RoundingParams.fromCornersRadius(7f)
val hierarchy = GenericDraweeHierarchyBuilder(resources)
.setRoundingParams(roundingParams)
.build()
frescoImageView.hierarchy = hierarchy
- Limitations : Certaines transformations ne s’appliquent qu’à des formats spécifiques (par exemple, JPEG) et certaines mises à l’échelle sont restreintes.
Prise en charge des animations
Les transitions fluides et le retour d’information utilisateur sont les piliers d’une excellente expérience utilisateur mobile. Les effets de fondu subtils évitent que le chargement des images ne semble brutal, tandis que les barres de progression rassurent les utilisateurs quant à l’arrivée du contenu. Les animations post-chargement — comme la rotation ou le rebond — peuvent ajouter une touche de personnalité supplémentaire, mettre en valeur des visuels clés et renforcer l’identité de la marque.
Effets de fondu
- Picasso : Fondu intégré basique (se déclenche chaque fois que l’image ne provient pas de la mémoire). Impossible de personnaliser la durée ; uniquement
fadeEnabled / fadeDisabled. - Glide :
- Utilisez
transition(DrawableTransitionOptions.withCrossFade(duration)). - Il prend en charge le fondu enchaîné (ancienne image sortante, nouvelle image entrante) ou un simple fondu de superposition. Si nécessaire, vous pouvez également définir des animations XML personnalisées.
- Utilisez
- Fresco :
Définissez la durée du fondu via le XML de la mise en page ou le code :
val builder = GenericDraweeHierarchyBuilder(resources)
val hierarchy = builder.setFadeDuration(3000).build()
frescoImageView.hierarchy = hierarchy
- Utilise toujours une approche de fondu enchaîné ; peut être gourmand en ressources avec de grandes listes.
Barres de progression
- Picasso :
- La méthode la plus simple : utilisez un
placeholder(R.drawable.progress_animation). - Ou implémentez une
Targetpersonnalisée pour afficher/masquer uneProgressBarpendant le chargement des images.
- La méthode la plus simple : utilisez un
- Glide :
- Une approche similaire utilise des espaces réservés ou un
RequestListenerpersonnalisé pour suivre l’état du chargement. - Certains développeurs remplacent
GlideModulepour intercepter et mesurer la progression plus précisément.
- Une approche similaire utilise des espaces réservés ou un
- Fresco :
- Dans XML, définissez
fresco:progressBarImage="@drawable/spinner".
- Dans XML, définissez
À partir du code :
val progressDrawable = ProgressBarDrawable().apply {
color = Color.YELLOW
backgroundColor = Color.BLUE
radius = 2
}
frescoImageView.hierarchy.setProgressBarImage(progressDrawable)
- Fresco affiche facilement des barres de progression indéfinies ou basées sur un pourcentage avec un minimum d’effort.
Animations post-chargement : Rotation d'image
- Picasso :
- Utilisez un
Callbackdansinto(...). DansonSuccess(), exécutez votre code d’animation (par exemple,startAnimation(rotateAnimation)).
- Utilisez un
- Glide :
- Implémentez un
RequestListeneret surchargezonResourceReady(). Exécutez votre animation là-bas.
- Implémentez un
- Fresco :
- Créez un
BaseControllerListener. DansonFinalImageSet(), déclenchez l’animation (frescoImageView.startAnimation(...)).
- Créez un
Fonctionnalités uniques
Au-delà de la mise en cache et de la transformation standard, chaque bibliothèque excelle dans des domaines spécifiques qui peuvent faire pencher la balance dans votre choix de développement. Voici un aperçu rapide de ce qui distingue chaque bibliothèque :
- Picasso : Minimaliste, faible encombrement. Idéal pour le chargement d’images simple. Il manque d’animations intégrées robustes, mais est facile à apprendre pour les débutants.
- Glide : Transformations riches, prise en charge intégrée des GIF, personnalisation flexible (par exemple, piles réseau personnalisées). Maintient plusieurs versions d’images dans le cache pour différentes tailles ou transformations.
- Fresco : Gestion innovante de la mémoire (stockage des images en dehors du tas Java). Gains de performance notables sur les anciens appareils Android. Le propre SimpleDraweeView peut simplifier les espaces réservés, les barres de progression et les transitions par fondu.
Tableau comparatif pour 2025
Vous trouverez ci-dessous un tableau comparatif concis mettant en évidence les principales différences entre Picasso, Glide et Fresco en 2025. Utilisez-le comme référence rapide pour décider quelle bibliothèque correspond le mieux aux exigences de chargement d’images de votre projet Android.
Taille de la bibliothèque
~121 Ko + ~849 méthodes
~440 Ko + ~2678 méthodes
~500 Ko (variable), utilisation de la mémoire du tas Java
Facilité d’utilisation
Élevée (très convivial pour les débutants)
Élevée (API riche, courbe d’apprentissage modérée)
Moyenne (SimpleDraweeView personnalisé + schémas d’utilisation différents)
Animation (fondu, fondu enchaîné)
Fondu intégré ou option de désactivation, non personnalisable
Transitions entièrement personnalisables (durée, fondu enchaîné, XML personnalisé)
Configuration de fondu simple ; toujours en fondu enchaîné ; peut être gourmand en ressources avec de grandes listes
Barres de progression
Nécessite des espaces réservés personnalisés ou une Target
Espaces réservés personnalisés ou remplacement de GlideModule
Configuration rapide via XML ou code, prend en charge les barres indéfinies et basées sur un pourcentage
Fonctionnalités de transformation
Fonctionnalités intégrées de base ; les transformations personnalisées nécessitent une interface Transformation
Fonctionnalités intégrées puissantes, transformations personnalisées faciles (BitmapTransformation, etc.)
Transformations avancées, beaucoup en XML ; les postprocesseurs personnalisés peuvent être plus complexes
Mise en cache
LRU (mémoire + disque) ; contrôle via memoryPolicy() et networkPolicy()
Cache à 4 niveaux ; permet de sauter facilement la mémoire ou le disque, clés personnalisées avancées
Cache à 3 niveaux (bitmap, mémoire encodée, disque) ; ImagePipeline pour un contrôle précis
Gains de performance
Bon pour les petites images, transformations limitées
Excellent pour les GIF, les transformations lourdes, les variantes d’images multiples
Très efficace en mémoire sur les anciens appareils, moins de surcharge de GC
Fonctionnalités phares
Faible empreinte, facile à intégrer, rapide à apprendre
Chargement de GIF, prise en charge des images vidéo, pile réseau personnalisée, API de transformation étendue
Images dans le tas ashmem, prise en charge des JPEG progressifs, espaces réservés et barres de progression intégrés
Conclusion
Picasso est idéal pour les tâches d’image simples où une configuration minimale et une petite taille d’APK sont primordiales.
Glide reste la référence pour les transformations complexes, la prise en charge des GIF et la mise en cache de variantes multiples, bien qu’il soit plus lourd en taille d’APK. Découvrez comment nous avons utilisé les capacités efficaces de chargement et de mise en cache d’images de Glide pour optimiser Android Bug Hunter, une solution mobile qui simplifie les tests manuels d’interface utilisateur et les tests à faible mémoire des applications Android.
Fresco excelle dans les scénarios sensibles à la mémoire, en particulier sur les anciens appareils ou dans les flux très chargés en images, grâce à son approche distinctive de stockage des images en dehors du tas Java standard.
Ces trois bibliothèques continueront de dominer le chargement d’images sur Android en 2025, chacune offrant des capacités robustes de mise en cache, de transformation et d’animation. Le meilleur choix dépend des besoins spécifiques de votre application, qu’il s’agisse d’une utilisation plus simple, de transitions avancées ou d’optimisation de la mémoire. Chez Redwerk, nous avons fourni des solutions Android pour les secteurs des télécommunications, de l’informatique et du commerce électronique. Nous sommes prêts et disposés à vous aider à affiner votre stratégie de chargement d’images. N’hésitez pas à nous contacter si vous souhaitez des conseils d’experts sur votre prochain projet.
Découvrez comment nous avons utilisé le chargement et la mise en cache d'images de Glide pour optimiser Android Bug Hunter, un outil Android pour les tests d'interface utilisateur et de faible mémoire