Como dimensionar uma imagem no ImageView para manter a proporção


526

Em Android, eu definido um ImageViewé layout_widthpara ser fill_parent(que ocupa toda a largura do telefone).

Se a imagem que eu coloco ImageViewfor maior que a layout_width, o Android a dimensionará, certo? Mas e a altura? Quando o Android dimensiona a imagem, ele mantém a proporção?

O que eu descobri é que há algum espaço em branco na parte superior e inferior do ImageViewquando o Android dimensiona uma imagem que é maior que a ImageView. Isso é verdade? Se sim, como posso eliminar esse espaço em branco?

Respostas:


799
  1. Sim, por padrão, o Android redimensionará sua imagem para caber no ImageView, mantendo a proporção. No entanto, verifique se você está configurando a imagem para o ImageView usando, em android:src="..."vez de android:background="...". src=faz com que ela dimensione a imagem mantendo a proporção, mas background=a escala e distorce a imagem para ajustá-la exatamente ao tamanho do ImageView. (Você pode usar um plano de fundo e uma fonte ao mesmo tempo, o que pode ser útil para exibir um quadro ao redor da imagem principal, usando apenas um ImageView.)

  2. Você também deve ver android:adjustViewBounds fazer o redimensionamento do ImageView para se ajustar à imagem redimensionada. Por exemplo, se você tiver uma imagem retangular no que normalmente seria um ImageView quadrado, AdjustViewBounds = true fará com que redimensione o ImageView para ser retangular também. Isso afeta como outras visualizações são dispostas em torno do ImageView.

    Então, como Samuh escreveu, você pode alterar a maneira como o padrão escala as imagens usando o android:scaleTypeparâmetro A propósito, a maneira mais fácil de descobrir como isso funciona seria simplesmente experimentar um pouco! Lembre-se de olhar os layouts no próprio emulador (ou em um telefone real), pois a visualização no Eclipse geralmente está errada.


18
É a mesma coisa, apenas feita em código, e não em XML. setImageBitmapé o mesmo que android:src="..."e setBackground...éandroid:background="..."
Steve Haley

4
@SuperUser também image.setImageDrawable(...)está android:src="..."em xml.
PureSpider

11
"android: AdjustViewBounds" é o mais útil aqui para anotar! se você não adicionar isso, provavelmente terá problemas com a borda / limites / contêiner do ImageView não sendo dimensionados corretamente.
irritada 84

2
src = vs background = foi a diferença para mim!
Christopher Rathgeb

21
android:adjustViewBoundsfoi a última peça do meu quebra-cabeça, obrigado!
precisa

281

Veja android:adjustViewBounds.

Defina como true se desejar que o ImageView ajuste seus limites para preservar a proporção da sua gaveta.


6
Esta é a correção correta para o problema. Estávamos vendo isso na visualização da imagem, onde a altura incluía todo esse espaço em branco extra. Não são "pixels transparentes", pois tivemos fill_parent para largura e wrap_content para altura. Se você não tiver AdjustViewBounds = true, receberá o espaço em branco extra. Depois de definir isso como verdadeiro, nosso problema desapareceu. Obrigado!
Christophercotton

3
obrigado, e configurá-lo para src em vez de segundo plano funcionou perfeitamente!
Cameron


1
Essa é a correção perfeita para o problema. Também para os tamanhos, use o contêiner pai para definir o tamanho e defina match_parent no ImageView. Isso resolve muitos problemas.
Nimila Hiranya

+1 para chegar ao ponto. Inicialmente, escrevi isso em uma frase mais "coloquial" e me impediu de enviá-la. Em vez de plumas plissadas, um PC foi.
23916 Jacksonkr

168

Para qualquer pessoa que tenha esse problema em particular. Você tem uma ImageViewlargura fill_parente uma altura dimensionadas proporcionalmente:

Adicione estes dois atributos ao seu ImageView:

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

E defina a ImageViewlargura fill_parente a altura como wrap_content.

Além disso, se você não deseja que sua imagem seja cortada, tente o seguinte:

 android:adjustViewBounds="true"
 android:layout_centerInParent="true"

16
Sim, mas sua imagem é cortada. A solução perfeita se estenderia à largura, manteria a proporção e não cortaria. Eu não tenho idéia do por que isso tem que ser tão difícil de fazer ...
Warpzit

1
Nem eu :( Desculpe se minha solução não ajudá-lo, mas ele me ajudou.
Kevin Parker

2
Kevin, o que você disse foi exatamente o que eu estava procurando, se o tamanho da imagem for menor que o da tela, ela será ampliada e centralizada, perfeita. Obrigado.
Soham 17/01

1
+1, exceto "(ou outro View)". AFAICT nenhuma outra visualização possui adjustViewBoundsou scaleTypeatributos.
LarsH 08/09

que tal usar android: scaleType = "centerInside" em vez de android: scaleType = "centerCrop"? Também não cortaria a imagem, mas garantiria que largura e altura sejam iguais ou inferiores à largura e altura da visualização de imagem :) Aqui está um bom guia visual para tipos de escalonamento: thoughtbot.com/blog/android-imageview-scaletype-a-visual- guide
vida

57

Se você deseja um ImageViewque seja dimensionado para cima e para baixo, mantendo a proporção adequada, adicione-o ao seu XML:

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

Adicione isto ao seu código:

// 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);

Demorei um pouco para que isso funcionasse, mas isso parece funcionar nos casos em que a imagem é menor que a largura da tela e maior que a largura da tela e não encaixa na imagem.


1
Por que não usar apenas android: scaleType = "centerCrop"?
Lukas Batteau

funciona como um encanto, obrigado. scaleType depende da situação, por exemplo, eu precisava exatamente disso.
David

Esta é uma maneira um pouco bárbara de redimensionar a vista. O que acontece se os limites da exibição mudarem depois que você definir o bitmap para o ImageView? É por isso que isso deve ser feito em onMeasure (), que pode ser implementado se você criar uma subclasse personalizada do ImageView.
Aron Lorincz 17/03/2014

1
Tudo que eu precisava era o fitCenter e adjustViewBounds, o resto do código, pelo menos para mim era desnecessário
kingargyle

Isso funciona para mim e não precisa adicionar nenhum código. Sem o AdjustViewBounds, se a largura da imagem era menor que a largura do ImageView, ela não estava aumentando, então a altura estava parando na altura nativa e, na largura, algumas bandas apareceram.
Cristi Băluță 4/04/19

15

Isso funcionou para mim:

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="39dip"
android:scaleType="centerCrop"
android:adjustViewBounds ="true"

10

isso resolveu meu problema

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

Não preserva a proporção da imagem para mim.
Dmitry

9

Abaixo do código Trabalhando para a imagem em escala como proporção:

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);

8

Dê uma olhada no ImageView.ScaleType para controlar e entender como o redimensionamento acontece em um ImageView. Quando a imagem é redimensionada (mantendo a proporção), as chances são de que a altura ou a largura da imagem se tornem menores que ImageViewas dimensões.


6

Use estas propriedades no ImageView para manter a proporção:

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

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:scaleType="fitXY"
    />

Somente essa resposta me ajudou. Obrigado!
Dmitry

6

É assim que funcionou para mim dentro de um ConstraintLayout:

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

Em seguida, no código, defino o drawable como:

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

Isso se ajusta bem à imagem, de acordo com sua proporção e a mantém no centro.


5

Eu tenho uma imagem menor que a tela. Para esticá-lo proporcionalmente ao máximo e centralizado na visualização, tive que usar o seguinte código:

<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" />

No entanto, lembre-se de que, se você tiver um layout relativo e alguns elementos definidos acima ou abaixo do ImageView, eles provavelmente serão sobrepostos pela imagem.


4

Se a qualidade da imagem diminuir em: use

android:adjustViewBounds="true"

ao invés de

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

3

Para quem deseja que a imagem se ajuste exatamente à visualização de imagem com o dimensionamento adequado e sem uso de recorte

imageView.setScaleType(ScaleType.FIT_XY);

onde imageView é a visualização que representa seu ImageView


4
Não, isso muda a proporção do aspecto. Os documentos dizem: "Dimensione em X e Y independentemente, para que o src corresponda exatamente ao dst. Isso pode alterar a proporção do src."
Rose Perrone 28/05

A propósito, este FIT_XY não pode ser usado para alterar a largura / altura da imagem para exibição na visualização de imagem.
Bay

3

Você pode calcular a largura da tela. E você pode escalar 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;
    }

calcular a largura da tela e a altura da imagem em escala pela largura da tela.

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

Depois que você pode dimensionar o bitmap.

Bitmap scaledBitmap=Bitmap.createScaledBitmap(bitmap, (int) screenWidth, (int) newHeight, true);

3

Ao fazer isso programaticamente, chame os setters na ordem correta:

imageView.setAdjustViewBounds(true)
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP)

2

Se você deseja que sua imagem ocupe o espaço máximo possível, a melhor opção seria

android:layout_weight="1"
android:scaleType="fitCenter"

2

Você não precisa de nenhum código java. Você só tem de :

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

A chave está no pai de correspondência para largura e altura


1

Tente usar o android:layout_gravityImageView:

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

O exemplo acima funcionou para mim.


1
android: layout_weight = "1" é a chave.
Nima

1

Eu tenho um algoritmo para dimensionar um bitmap para melhor ajustar as dimensões do contêiner, mantendo sua proporção. Encontre minha solução aqui

Espero que isso ajude alguém na estrada!


0

Eu uso isso:

<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" />

0

no caso de usar cardviewpara arredondamento imageviewe fixo android:layout_heightpara cabeçalho, isso funcionou para mim carregar a imagem comGlide

    <?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>

0

Você pode dimensionar a imagem que também reduzirá o tamanho da sua imagem. Existe uma biblioteca para você baixar e usar. https://github.com/niraj124124/Images-Files-scale-and-compress.git

Como usar 1) Importe o compressor-v1.0. jar para o seu projeto. 2) Adicione o código de amostra abaixo para testar. ResizeLimiter resize = ImageResizer.build (); resize.scale ("inputImagePath", "outputImagePath", imageWidth, imageHeight); Muitos outros métodos existem de acordo com sua exigência


0

Passe seu ImageView e, com base na altura e largura da tela, você poderá

    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);
    }


0

Resposta rápida:

<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" />

-5
imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, 130, 110, false));
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.