Comment mettre à l'échelle une image dans ImageView pour conserver le rapport hauteur / largeur

526

Dans les applications, I définie une ImageView« est layout_widthd'être fill_parent(qui occupe toute la largeur du téléphone).

Si l'image que je mets ImageViewest plus grande que la layout_width, Android la redimensionnera, non? Mais qu'en est-il de la hauteur? Lorsque Android redimensionnera l'image, conservera-t-il les proportions?

Ce que je découvre, c'est qu'il y a un espace blanc en haut et en bas du ImageViewlorsque Android redimensionne une image qui est plus grande que le ImageView. Est-ce vrai? Si oui, comment puis-je éliminer cet espace blanc?

Michael
la source

Réponses:

799
  1. Oui, par défaut, Android réduira votre image pour l'adapter à l'ImageView, en conservant le rapport d'aspect. Cependant, assurez-vous que vous définissez l'image sur ImageView en utilisant android:src="..."plutôt que android:background="...". src=le fait redimensionner l'image en conservant le rapport d'aspect, mais background=le redimensionne et déforme l'image pour l'adapter exactement à la taille de l'ImageView. (Vous pouvez utiliser un arrière-plan et une source en même temps, ce qui peut être utile pour des choses comme l'affichage d'un cadre autour de l'image principale, en utilisant une seule ImageView.)

  2. Vous devriez également voir android:adjustViewBoundspour que ImageView se redimensionne lui-même pour s'adapter à l'image redimensionnée. Par exemple, si vous avez une image rectangulaire dans ce qui serait normalement une ImageView carrée, adjustViewBounds = true le redimensionnera également pour qu'elle soit rectangulaire. Cela affecte ensuite la façon dont les autres vues sont disposées autour de l'ImageView.

    Ensuite, comme Samuh l'a écrit, vous pouvez changer la façon dont il redimensionne les images par défaut à l'aide du android:scaleTypeparamètre. Soit dit en passant, la façon la plus simple de découvrir comment cela fonctionne aurait simplement été d'expérimenter un peu vous-même! N'oubliez pas de regarder les dispositions dans l'émulateur lui-même (ou un téléphone réel) car l'aperçu dans Eclipse est généralement faux.

Steve Haley
la source
18
C'est la même chose, juste faite en code plutôt qu'en XML. setImageBitmapest le même que android:src="..."et setBackground...estandroid:background="..."
Steve Haley
4
@SuperUser image.setImageDrawable(...)est également android:src="..."en XML.
PureSpider
11
"android: adjustViewBounds" est le point pratique ici à noter! si vous n'ajoutez pas cela, vous aurez très probablement des problèmes avec la mise à l'échelle de la bordure / limites / conteneur ImageView.
Angry 84
2
src = vs background = était la différence pour moi!
Christopher Rathgeb
21
android:adjustViewBoundsétait la dernière pièce de mon puzzle, merci!
themarketka
281

Tu vois android:adjustViewBounds.

Affectez la valeur true si vous souhaitez que ImageView ajuste ses limites afin de conserver le rapport hauteur / largeur de son dessin.

Gratzi
la source
6
Il s'agit du correctif correct pour le problème. Nous l'avions sur notre image, où la hauteur comprenait tous ces espaces supplémentaires. Ce ne sont pas des "pixels transparents", car nous avions fill_parent pour la largeur et wrap_content pour la hauteur. Si vous n'avez pas adjustViewBounds = true, alors vous obtenez l'espace supplémentaire. Après avoir réglé cela sur vrai, notre problème a disparu. Merci!
christophercotton
3
merci, cela et le mettre à src au lieu de fond a parfaitement fonctionné!
Cameron
1
Ceci est la solution parfaite pour le problème. Pour les tailles également, utilisez le conteneur parent pour définir la taille et définissez match_parent dans ImageView. Cela résout beaucoup de problèmes.
Nimila Hiranya
+1 pour arriver au point. J'ai d'abord écrit cela dans une phrase plus "familière" et j'ai été empêché de le soumettre. Plutôt que de plumes à volants, un PC est allé.
Jacksonkr
168

À toute autre personne ayant ce problème particulier. Vous avez un objet ImageViewdont vous souhaitez avoir une largeur fill_parentet une hauteur ajustées proportionnellement:

Ajoutez ces deux attributs à votre ImageView:

android:adjustViewBounds="true"
android:scaleType="centerCrop"

Et définissez la ImageViewlargeur fill_parentet la hauteur sur wrap_content.

De plus, si vous ne voulez pas que votre image soit recadrée, essayez ceci:

 android:adjustViewBounds="true"
 android:layout_centerInParent="true"
Kevin Parker
la source
16
Oui mais votre image est recadrée. La solution parfaite s'étendrait à la largeur, maintiendrait le rapport d'aspect et ne recadrerait pas. Je ne sais pas pourquoi cela doit être si difficile à faire ...
Warpzit
1
Moi non plus :( Désolé si ma solution ne vous a pas aidé, mais elle m'a aidé.
Kevin Parker
2
Kevin, ce que vous avez dit était exactement ce que je cherchais, si la taille de l'image est inférieure à celle de l'écran, elle est agrandie et centrée, parfaite. Merci.
Soham
1
+1, sauf pour "(ou autre View)". AFAICT aucune autre vue n'a adjustViewBoundsni scaleTypeattribut.
LarsH
que diriez-vous d'utiliser android: scaleType = "centerInside" au lieu d'Android: scaleType = "centerCrop"? Il ne recadrerait pas non plus l'image, mais garantirait que la largeur et la hauteur sont inférieures ou égales à la largeur et à la hauteur de l'imageview :) guide
vida
57

Si vous voulez un ImageViewqui évolue à la fois vers le haut et vers le bas tout en conservant le rapport d'aspect approprié, ajoutez ceci à votre XML:

android:adjustViewBounds="true"
android:scaleType="fitCenter"

Ajoutez ceci à votre code:

// We need to adjust the height if the width of the bitmap is
// smaller than the view width, otherwise the image will be boxed.
final double viewWidthToBitmapWidthRatio = (double)image.getWidth() / (double)bitmap.getWidth();
image.getLayoutParams().height = (int) (bitmap.getHeight() * viewWidthToBitmapWidthRatio);

Il m'a fallu un certain temps pour que cela fonctionne, mais cela semble fonctionner dans les cas où l'image est plus petite que la largeur de l'écran et plus grande que la largeur de l'écran, et elle ne encadre pas l'image.

Kevin
la source
1
Pourquoi ne pas simplement utiliser Android: scaleType = "centerCrop"?
Lukas Batteau
fonctionne comme un charme, merci. scaleType dépend de la situation, par exemple, j'avais besoin exactement de cela.
David
C'est une façon un peu barbare de redimensionner la vue. Que se passe-t-il si les limites de la vue changent après avoir défini le bitmap sur ImageView? C'est pourquoi cela devrait être fait dans onMeasure (), qui peut être implémenté si vous créez une sous-classe personnalisée d'ImageView.
Aron Lorincz
1
Tout ce dont j'avais besoin était le fitCenter et adjustViewBounds, le reste du code au moins pour moi n'était pas nécessaire
kingargyle
Cela fonctionne pour moi et n'a pas besoin d'ajouter de code. Sans l'ajustViewBounds si la largeur de l'image était inférieure à la largeur de l'imageView, elle ne s'agrandissait pas, donc la hauteur s'arrêtait à la hauteur native et sur la largeur certaines bandes apparaissaient.
Cristi Băluță
15

Cela a fonctionné pour moi:

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="39dip"
android:scaleType="centerCrop"
android:adjustViewBounds ="true"
Mike6679
la source
10

cela a résolu mon problème

android:adjustViewBounds="true"
android:scaleType="fitXY"
shafiq-ur-rehman
la source
Cela ne préserve pas le rapport hauteur / largeur de l'image pour moi.
Dmitry
9

Code ci-dessous Travailler pour l'image à l'échelle comme rapport d'aspect:

Bitmap bitmapImage = BitmapFactory.decodeFile("Your path");
int nh = (int) ( bitmapImage.getHeight() * (512.0 / bitmapImage.getWidth()) );
Bitmap scaled = Bitmap.createScaledBitmap(bitmapImage, 512, nh, true);
your_imageview.setImageBitmap(scaled);
Mukesh Parmar
la source
8

Jetez un œil à ImageView.ScaleType pour contrôler et comprendre la façon dont le redimensionnement se produit dans un fichier ImageView. Lorsque l'image est redimensionnée (tout en conservant son rapport hauteur / largeur), il est probable que la hauteur ou la largeur de l'image devienne inférieure ImageViewaux dimensions de.

Samuh
la source
6

Utilisez ces propriétés dans ImageView pour conserver les proportions:

android:adjustViewBounds="true"
android:scaleType="fitXY"

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:scaleType="fitXY"
    />
Atif Mahmood
la source
Seule cette réponse m'a aidé. Merci!
Dmitry
6

Voici comment cela a fonctionné pour moi dans un ConstraintLayout:

<ImageView
    android:id="@+id/myImg"
    android:layout_width="300dp"
    android:layout_height="300dp"
    android:scaleType="fitCenter"
    android:adjustViewBounds="true"/>

Ensuite, dans le code, j'ai défini le drawable comme:

ImageView imgView = findViewById(R.id.myImg);
imgView.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.image_to_show, null));

Cela correspond bien à l'image en fonction de son rapport d'aspect et la maintient au centre.

Jeet
la source
5

J'ai une image plus petite que l'écran. Pour l'avoir étiré proportionnellement au maximum et centré dans la vue, j'ai dû utiliser le code suivant:

<ImageView
    android:id="@+id/my_image"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_centerInParent="true"
    android:adjustViewBounds="true"
    android:layout_weight="1"
    android:scaleType="fitCenter" />

Gardez cependant à l'esprit que si vous avez une disposition relative et que certains éléments sont définis au-dessus ou au-dessous de ImageView, ils seront très probablement chevauchés par l'image.

halxinate
la source
4

Si la qualité de l'image diminue dans: utiliser

android:adjustViewBounds="true"

au lieu de

android:adjustViewBounds="true"
android:scaleType="fitXY"
developerSumit
la source
3

Pour tous ceux d'entre vous qui souhaitent que l'image corresponde exactement à l'image avec une mise à l'échelle appropriée et sans recadrage

imageView.setScaleType(ScaleType.FIT_XY);

où imageView est la vue représentant votre ImageView

oneConsciousness
la source
4
Non, cela change la ration d'aspect. Les documents disent: "Echelle en X et Y indépendamment, afin que src corresponde exactement à dst. Cela peut changer le rapport d'aspect du src."
Rose Perrone
Soit dit en passant, ce FIT_XY ne peut pas être utilisé pour modifier la largeur / hauteur de l'image à afficher sur l'image.
Bay
3

Vous pouvez calculer la largeur de l'écran. Et vous pouvez mettre à l'échelle le bitmap.

 public static float getScreenWidth(Activity activity) {
        Display display = activity.getWindowManager().getDefaultDisplay();
        DisplayMetrics outMetrics = new DisplayMetrics();
        display.getMetrics(outMetrics);
        float pxWidth = outMetrics.widthPixels;
        return pxWidth;
    }

calculer la largeur de l'écran et la hauteur de l'image mise à l'échelle par la largeur de l'écran.

float screenWidth=getScreenWidth(act)
  float newHeight = screenWidth;
  if (bitmap.getWidth() != 0 && bitmap.getHeight() != 0) {
     newHeight = (screenWidth * bitmap.getHeight()) / bitmap.getWidth();
  }

Une fois que vous pouvez mettre à l'échelle le bitmap.

Bitmap scaledBitmap=Bitmap.createScaledBitmap(bitmap, (int) screenWidth, (int) newHeight, true);
android_developer
la source
3

Lorsque vous faites cela par programmation, assurez-vous d'appeler les setters dans le bon ordre:

imageView.setAdjustViewBounds(true)
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP)
lukas
la source
2

Si vous voulez que votre image occupe le maximum d'espace possible, la meilleure option serait

android:layout_weight="1"
android:scaleType="fitCenter"
Mohsen Afshin
la source
2

Vous n'avez pas besoin de code java. Il vous suffit de:

<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />

La clé est dans le parent de correspondance pour la largeur et la hauteur

Romu Dizzy
la source
1

Essayez d'utiliser android:layout_gravitypour ImageView:

android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_weight="1"

L'exemple ci-dessus a fonctionné pour moi.

ITisha
la source
1
android: layout_weight = "1" est la clé.
nima
1

J'ai un algorithme pour mettre à l'échelle un bitmap pour mieux s'adapter aux dimensions du conteneur, en conservant son rapport d'aspect. Veuillez trouver ma solution ici

J'espère que cela aide quelqu'un sur la voie!

Parth Kapoor
la source
0

J'utilise ceci:

<ImageView
android:id="@+id/logo"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:scaleType="centerInside"
android:src="@drawable/logo" />
Flavio Capaccio
la source
0

en cas d'utilisation cardviewpour l'arrondi imageviewet fixé android:layout_heightpour l'en-tête, cela a fonctionné pour moi de charger l'image avecGlide

    <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:tools="http://schemas.android.com/tools"
             android:layout_width="match_parent"
             android:layout_height="220dp"
             xmlns:card_view="http://schemas.android.com/apk/res-auto"
             >

    <android.support.v7.widget.CardView
            android:id="@+id/card_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center|top"
            card_view:cardBackgroundColor="@color/colorPrimary"
            card_view:cardCornerRadius="10dp"
            card_view:cardElevation="10dp"
            card_view:cardPreventCornerOverlap="false"
            card_view:cardUseCompatPadding="true">

        <ImageView
                android:adjustViewBounds="true"
                android:maxHeight="220dp"
                android:id="@+id/iv_full"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:scaleType="fitCenter"/>

    </android.support.v7.widget.CardView>
</FrameLayout>
lvl4fi4
la source
0

Vous pouvez redimensionner l'image qui réduira également la taille de votre image. Il existe une bibliothèque que vous pouvez télécharger et utiliser. https://github.com/niraj124124/Images-Files-scale-and-compress.git

Comment utiliser 1) Importez le compresseur-v1.0. pot à votre projet. 2) Ajoutez l'exemple de code ci-dessous pour tester. ResizeLimiter resize = ImageResizer.build (); resize.scale ("inputImagePath", "outputImagePath", imageWidth, imageHeight); Beaucoup plus de méthodes sont là selon votre condition

Niraj
la source
0

Passez votre ImageView et en fonction de la hauteur et de la largeur de l'écran, vous pouvez le faire

    public void setScaleImage(EventAssetValueListenerView view){
        // Get the ImageView and its bitmap
        Drawable drawing = view.getDrawable();
        Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();
        // Get current dimensions
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        float xScale = ((float) 4) / width;
        float yScale = ((float) 4) / height;
        float scale = (xScale <= yScale) ? xScale : yScale;

        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale);

        Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
        BitmapDrawable result = new BitmapDrawable(scaledBitmap);
        width = scaledBitmap.getWidth();
        height = scaledBitmap.getHeight();

        view.setImageDrawable(result);

        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams();
        params.width = width;
        params.height = height;
        view.setLayoutParams(params);
    }

ppreetikaa
la source
0

Réponse rapide:

<ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="center"
        android:src="@drawable/yourImage"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
myworldbox
la source
-5
imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, 130, 110, false));
user2099162
la source