Cette réponse est résumée dans Chargement efficace de grandes images bitmap
qui explique comment utiliser inSampleSize pour charger une version bitmap réduite.
En particulier, les bitmaps de pré-mise à l'échelle expliquent les détails des différentes méthodes, comment les combiner et quelles sont les plus efficaces en mémoire.
Il existe trois méthodes dominantes pour redimensionner une image bitmap sur Android qui ont des propriétés de mémoire différentes:
API createScaledBitmap
Cette API prendra un bitmap existant et créera un NOUVEAU bitmap avec les dimensions exactes que vous avez sélectionnées.
Du côté positif, vous pouvez obtenir exactement la taille d'image que vous recherchez (quel que soit son aspect). Mais l'inconvénient est que cette API nécessite un bitmap existant pour fonctionner . Cela signifie que l'image devrait être chargée, décodée et un bitmap créé avant de pouvoir créer une nouvelle version plus petite. C'est idéal pour obtenir vos dimensions exactes, mais horrible en termes de surcharge de mémoire supplémentaire. En tant que tel, c'est une sorte de rupture pour la plupart des développeurs d'applications qui ont tendance à être conscients de leur mémoire
Indicateur inSampleSize
BitmapFactory.Options
a une propriété notée car inSampleSize
cela redimensionnera votre image lors de son décodage, pour éviter d'avoir à décoder en une image bitmap temporaire. Cette valeur entière utilisée ici chargera une image à une taille réduite 1 / x. Par exemple, le réglage inSampleSize
sur 2 renvoie une image qui fait la moitié de la taille et le réglage sur 4 renvoie une image qui fait 1 / 4ème de la taille. Fondamentalement, les tailles d'image seront toujours plus petites que la taille de votre source.
Du point de vue de la mémoire, l'utilisation inSampleSize
est une opération très rapide. En effet, il ne décodera que chaque Xème pixel de votre image dans votre bitmap résultant. Cependant, il y a deux problèmes principaux inSampleSize
:
Cela ne vous donne pas de résolutions exactes . Cela ne réduit la taille de votre bitmap que d'une puissance de 2.
Il ne produit pas le meilleur redimensionnement de qualité . La plupart des filtres de redimensionnement produisent de belles images en lisant des blocs de pixels, puis en les pondérant pour produire le pixel redimensionné en question. inSampleSize
évite tout cela en lisant simplement tous les quelques pixels. Le résultat est assez performant et la mémoire est faible, mais la qualité en souffre.
Si vous ne faites que réduire votre image d'une taille pow2 et que le filtrage n'est pas un problème, vous ne pouvez pas trouver de méthode plus efficace en mémoire (ou plus efficace en termes de performances) que inSampleSize
.
Indicateurs inScaled, inDensity, inTargetDensity
Si vous avez besoin de mettre à l'échelle une image à une dimension qui n'est pas égale à une puissance de deux, vous aurez besoin des indicateurs inScaled
, inDensity
et inTargetDensity
de BitmapOptions
. Une fois l' inScaled
indicateur défini, le système dérivera la valeur de mise à l'échelle à appliquer à votre bitmap en divisant le inTargetDensity
par les inDensity
valeurs.
mBitmapOptions.inScaled = true;
mBitmapOptions.inDensity = srcWidth;
mBitmapOptions.inTargetDensity = dstWidth;
// will load & resize the image to be 1/inSampleSize dimensions
mCurrentBitmap = BitmapFactory.decodeResources(getResources(),
mImageIDs, mBitmapOptions);
L'utilisation de cette méthode redimensionnera votre image et lui appliquera également un `` filtre de redimensionnement '', c'est-à-dire que le résultat final sera meilleur car des mathématiques supplémentaires ont été prises en compte lors de l'étape de redimensionnement. Mais attention: cette étape de filtrage supplémentaire prend du temps de traitement supplémentaire et peut rapidement s'additionner pour les grandes images, ce qui entraîne des redimensionnements lents et des allocations de mémoire supplémentaires pour le filtre lui-même.
Ce n'est généralement pas une bonne idée d'appliquer cette technique à une image beaucoup plus grande que la taille souhaitée, en raison de la surcharge de filtrage supplémentaire.
Combinaison magique
Du point de vue de la mémoire et des performances, vous pouvez combiner ces options pour obtenir les meilleurs résultats. (réglage de la inSampleSize
, inScaled
, inDensity
et inTargetDensity
drapeaux)
inSampleSize
sera d'abord appliqué à l'image, l'amenant à la prochaine puissance de deux PLUS GRANDE que votre taille cible. Ensuite, inDensity
& inTargetDensity
sont utilisés pour mettre à l'échelle le résultat aux dimensions exactes que vous souhaitez, en appliquant une opération de filtre pour nettoyer l'image.
La combinaison de ces deux éléments est une opération beaucoup plus rapide, car l' inSampleSize
étape réduira le nombre de pixels dont l'étape basée sur la densité résultante aura besoin pour appliquer son filtre de redimensionnement.
mBitmapOptions.inScaled = true;
mBitmapOptions.inSampleSize = 4;
mBitmapOptions.inDensity = srcWidth;
mBitmapOptions.inTargetDensity = dstWidth * mBitmapOptions.inSampleSize;
// will load & resize the image to be 1/inSampleSize dimensions
mCurrentBitmap = BitmapFactory.decodeFile(fileName, mBitmapOptions);
Si vous avez besoin d'adapter une image à des dimensions spécifiques et d' un filtrage plus agréable, cette technique est le meilleur pont pour obtenir la bonne taille, mais effectuée dans une opération rapide et à faible encombrement mémoire.
Obtenir les dimensions de l'image
Obtenir la taille de l'image sans décoder l'image entière Pour redimensionner votre bitmap, vous aurez besoin de connaître les dimensions entrantes. Vous pouvez utiliser l' inJustDecodeBounds
indicateur pour vous aider à obtenir les dimensions de l'image, sans avoir besoin de décoder réellement les données de pixel.
// Decode just the boundaries
mBitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileName, mBitmapOptions);
srcWidth = mBitmapOptions.outWidth;
srcHeight = mBitmapOptions.outHeight;
//now go resize the image to the size you want
Vous pouvez utiliser cet indicateur pour décoder d'abord la taille, puis calculer les valeurs appropriées pour la mise à l'échelle en fonction de votre résolution cible.