So skalieren Sie ein Bild in ImageView, um das Seitenverhältnis beizubehalten


526

In Android, definierte ich eine ImageView‚s layout_widthzu sein fill_parent(was die gesamte Breite des Telefons aufgreift).

Wenn das Bild, das ich eingefügt habe, ImageViewgrößer als das ist layout_width, wird es von Android skaliert, oder? Aber was ist mit der Höhe? Wenn Android das Bild skaliert, bleibt das Seitenverhältnis erhalten?

Was ich herausfinde, ist, dass es oben und unten einen Leerraum gibt, ImageViewwenn Android ein Bild skaliert, das größer als das ist ImageView. Ist das wahr? Wenn ja, wie kann ich diesen Leerraum entfernen?

Antworten:


799
  1. Ja, standardmäßig verkleinert Android Ihr Bild, um es an die ImageView anzupassen, wobei das Seitenverhältnis beibehalten wird. Stellen Sie jedoch sicher, dass Sie das Bild mit android:src="..."anstatt auf ImageView einstellen android:background="...". src=Hiermit wird das Bild skaliert, wobei das Seitenverhältnis beibehalten wird. Das Bild wird jedoch background=skaliert und verzerrt, damit es genau an die Größe der ImageView angepasst wird. (Sie können jedoch gleichzeitig einen Hintergrund und eine Quelle verwenden. Dies kann hilfreich sein, wenn Sie beispielsweise mit nur einer ImageView einen Rahmen um das Hauptbild anzeigen möchten.)

  2. Sie sollten auch sehen android:adjustViewBounds, dass sich die Größe der ImageView an das neu skalierte Bild anpasst. Wenn Sie beispielsweise ein rechteckiges Bild in einer normalerweise quadratischen ImageView haben, wird durch Anpassen von ViewVounds = true die Größe der ImageView ebenfalls auf rechteckig geändert. Dies wirkt sich dann darauf aus, wie andere Ansichten in der ImageView angeordnet sind.

    Dann können Sie, wie Samuh schrieb, die Art und Weise ändern, wie Bilder standardmäßig skaliert werden, indem Sie den android:scaleTypeParameter verwenden. Der einfachste Weg, um herauszufinden, wie das funktioniert, wäre übrigens gewesen, selbst ein bisschen zu experimentieren! Denken Sie daran, die Layouts im Emulator selbst (oder auf einem tatsächlichen Telefon) zu betrachten, da die Vorschau in Eclipse normalerweise falsch ist.


18
Das ist das Gleiche, nur in Code anstatt in XML. setImageBitmapist das gleiche wie android:src="..."und setBackground...istandroid:background="..."
Steve Haley

4
@ SuperUser image.setImageDrawable(...)ist auch android:src="..."in XML.
PureSpider

11
"android: adjustViewBounds" ist hier praktisch! Wenn Sie dies nicht hinzufügen, treten höchstwahrscheinlich Probleme mit der nicht korrekten Skalierung von ImageView-Rahmen / -Begrenzungen / -Containern auf.
Wütend 84

2
src = vs background = war der Unterschied für mich!
Christopher Rathgeb

21
android:adjustViewBoundswar das letzte Stück zu meinem Puzzle, danke!
themarketka

281

Siehe android:adjustViewBounds.

Setzen Sie dies auf true, wenn Sie möchten, dass ImageView seine Grenzen anpasst, um das Seitenverhältnis des Zeichnungsobjekts beizubehalten.


6
Dies ist die richtige Lösung für das Problem. Wir hatten dies in unserer Bildansicht, in der die Höhe all diese zusätzlichen Leerzeichen enthielt. Es sind keine "transparenten Pixel", da wir fill_parent für width und wrap_content für height hatten. Wenn Sie nicht adjustViewBounds = true haben, erhalten Sie das zusätzliche Leerzeichen. Nachdem wir dies auf true gesetzt hatten, verschwand unser Problem. Vielen Dank!
Christophercotton

3
danke, das und das Setzen auf src anstelle von Hintergrund hat perfekt funktioniert!
Cameron


1
Dies ist die perfekte Lösung für das Problem. Verwenden Sie auch für die Größen den übergeordneten Container, um die Größe festzulegen, und legen Sie match_parent in der ImageView fest. Dies löst viele Probleme.
Nimila Hiranya

+1 für den Punkt. Ich schrieb das anfangs in einer "umgangssprachlicheren" Formulierung und hinderte mich daran, es einzureichen. Anstatt Federn zu kräuseln, ging ein PC.
Jacksonkr

168

An alle anderen, die dieses spezielle Problem haben. Sie haben eine ImageView, deren Breite fill_parentund Höhe proportional skaliert werden sollen:

Fügen Sie diese beiden Attribute hinzu ImageView:

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

Und stellen Sie die ImageViewBreite fill_parentund Höhe auf ein wrap_content.

Wenn Sie nicht möchten, dass Ihr Bild zugeschnitten wird, versuchen Sie Folgendes:

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

16
Ja, aber Ihr Bild wird zugeschnitten. Die perfekte Lösung würde sich auf die Breite dehnen, das Seitenverhältnis beibehalten und nicht beschneiden. Ich habe keine Ahnung, warum dies so schwierig sein muss ...
Warpzit

1
Ich auch :( Entschuldigung, wenn meine Lösung Ihnen nicht geholfen hat, aber sie hat mir geholfen.
Kevin Parker

2
Kevin, was du gesagt hast, war genau das, wonach ich gesucht habe. Wenn die Größe des Bildes kleiner als die des Bildschirms ist, wird es vergrößert und zentriert, perfekt. Vielen Dank.
Soham

1
+1, außer "(oder andere View)". AFAICT hat keine andere Ansicht adjustViewBoundsoder scaleTypeAttribute.
LarsH

Wie wäre es mit android: scaleType = "centerInside" anstelle von android: scaleType = "centerCrop"? Es würde auch nicht das Bild zuschneiden, sondern sicherstellen, dass sowohl Breite als auch Höhe kleiner oder gleich der Breite und Höhe der Bildansicht sind :) Hier ist eine gute visuelle Anleitung für Skalentypen : oughtbot.com/blog/android-imageview-scaletype-a-visual- Führer
Vida

57

Wenn Sie möchten, ImageViewdass beide skaliert werden, während das richtige Seitenverhältnis beibehalten wird, fügen Sie dies Ihrem XML hinzu:

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

Fügen Sie dies Ihrem Code hinzu:

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

Es hat eine Weile gedauert, bis dies funktioniert hat, aber dies scheint in den Fällen zu funktionieren, in denen das Bild kleiner als die Bildschirmbreite und größer als die Bildschirmbreite ist und das Bild nicht verpackt wird.


1
Warum nicht einfach android: scaleType = "centerCrop" verwenden?
Lukas Batteau

funktioniert wie ein Zauber, danke. scaleType hängt von der Situation ab, zum Beispiel brauchte ich genau das.
David

Dies ist eine etwas barbarische Methode, um die Größe der Ansicht zu ändern. Was passiert, wenn sich die Ansichtsgrenzen ändern, nachdem Sie die Bitmap auf ImageView festgelegt haben? Aus diesem Grund sollte dies in onMeasure () erfolgen, das implementiert werden kann, wenn Sie eine benutzerdefinierte Unterklasse von ImageView erstellen.
Aron Lorincz

1
Alles was ich brauchte war das fitCenter und adjustViewBounds, der Rest des Codes war zumindest für mich unnötig
kingargyle

Dies funktioniert für mich und muss keinen Code hinzufügen. Ohne die adjustViewBounds wurde die Bildbreite, wenn sie kleiner als die imageView-Breite war, nicht vergrößert, sodass die Höhe auf die native Höhe angehalten wurde und auf der Breite einige Bänder angezeigt wurden.
Cristi Băluță

15

Das hat bei mir funktioniert:

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

10

Das hat mein Problem gelöst

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

Das Seitenverhältnis des Bildes bleibt für mich nicht erhalten.
Dmitry

9

Unterer Code Arbeiten für Skalierungsbild als Seitenverhältnis:

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

Schauen Sie sich ImageView.ScaleType an, um zu steuern und zu verstehen, wie die Größenänderung in einem erfolgt ImageView. Wenn die Bildgröße geändert wird (unter Beibehaltung des Seitenverhältnisses), besteht die Möglichkeit, dass entweder die Höhe oder Breite des Bilds kleiner als ImageViewdie Abmessungen des Bildes wird .


6

Verwenden Sie diese Eigenschaften in ImageView, um das Seitenverhältnis beizubehalten:

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

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

Nur diese Antwort hat mir geholfen. Vielen Dank!
Dmitry

6

So hat es bei mir in einem ConstraintLayout funktioniert:

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

Dann setze ich im Code das Zeichenbare wie folgt:

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

Dies passt gut zum Bildverhältnis und hält es in der Mitte.


5

Ich habe ein Bild, das kleiner als der Bildschirm ist. Um es proportional zum Maximum zu dehnen und in der Ansicht zu zentrieren, musste ich den folgenden Code verwenden:

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

Beachten Sie jedoch, dass einige Elemente, die über ein relatives Layout verfügen und so eingestellt sind, dass sie sich über oder unter der ImageView befinden, höchstwahrscheinlich vom Bild überlappt werden.


4

Wenn die Bildqualität abnimmt: Verwenden Sie

android:adjustViewBounds="true"

anstatt

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

3

Für alle unter Ihnen, die möchten, dass das Bild genau der Bildansicht mit der richtigen Skalierung und ohne Zuschneiden entspricht

imageView.setScaleType(ScaleType.FIT_XY);

Dabei ist imageView die Ansicht, die Ihre ImageView darstellt


4
Nein, dies ändert das Seitenverhältnis. In den Dokumenten heißt es: "Skalieren Sie X und Y unabhängig voneinander, sodass src genau mit dst übereinstimmt. Dies kann das Seitenverhältnis von src ändern."
Rose Perrone

Übrigens kann dieses FIT_XY nicht zum Ändern der Breite / Höhe des Bildes für die Anzeige in der Bildansicht verwendet werden.
Bay

3

Sie können die Bildschirmbreite berechnen. Und Sie können die Bitmap skalieren.

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

Berechnen Sie die Bildschirmbreite und die skalierte Bildhöhe anhand der Bildschirmbreite.

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

Nachdem Sie die Bitmap skalieren können.

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

3

Wenn Sie dies programmgesteuert tun, rufen Sie die Setter in der richtigen Reihenfolge auf:

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

2

Wenn Sie möchten, dass Ihr Bild den maximal möglichen Platz einnimmt, ist dies die beste Option

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

2

Du brauchst keinen Java-Code. Du musst nur :

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

Der Schlüssel befindet sich im übergeordneten Element für Breite und Höhe


1

Versuchen Sie es mit android:layout_gravityImageView:

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

Das obige Beispiel hat bei mir funktioniert.


1
android: layout_weight = "1" ist der Schlüssel.
Nima

1

Ich habe einen Algorithmus, um eine Bitmap so zu skalieren, dass sie am besten zu den Containerabmessungen passt, wobei das Seitenverhältnis beibehalten wird. Bitte finden meine Lösung hier

Hoffe, das hilft jemandem auf der Straße!


0

Ich benutze das:

<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

Im Falle der Verwendung cardviewzum Runden imageviewund Fixieren android:layout_heightfür den Header funktionierte dies für mich, um das Bild mit zu ladenGlide

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

Sie können ein Bild skalieren, das auch die Größe Ihres Bildes verringert. Es gibt eine Bibliothek dafür, die Sie herunterladen und verwenden können. https://github.com/niraj124124/Images-Files-scale-and-compress.git

Verwendung 1) Importieren Sie den Compressor-v1.0. Glas zu Ihrem Projekt. 2) Fügen Sie zum Testen den folgenden Beispielcode hinzu. ResizeLimiter resize = ImageResizer.build (); resize.scale ("inputImagePath", "outputImagePath", imageWidth, imageHeight); Je nach Ihren Anforderungen gibt es viele weitere Methoden


0

Übergeben Sie Ihre ImageView und basierend auf Bildschirmhöhe und -breite können Sie sie erstellen

    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

Schnelle Antwort:

<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));
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.