Bagaimana skala Gambar di ImageView untuk menjaga rasio aspek


526

Di Android, saya mendefinisikan ImageView's layout_widthto be fill_parent(yang mengambil lebar penuh ponsel).

Jika gambar yang saya masukkan ImageViewlebih besar dari itu layout_width, Android akan skala itu, kan? Tapi bagaimana dengan tinggi? Saat Android mengukur gambar, apakah ini akan menjaga rasio aspek?

Apa yang saya temukan adalah ada ruang putih di bagian atas dan bawah ImageView ketika Android skala gambar yang lebih besar dari ImageView. Benarkah? Jika ya, bagaimana saya bisa menghilangkan ruang putih itu?

Jawaban:


799
  1. Ya, secara default Android akan menurunkan skala gambar Anda agar sesuai dengan ImageView, mempertahankan rasio aspek. Namun, pastikan Anda mengatur gambar ke ImageView menggunakan android:src="..."daripada android:background="...". src=membuatnya skala gambar mempertahankan aspek rasio, tetapi background=membuatnya skala dan mendistorsi gambar agar pas dengan ukuran ImageView. (Anda dapat menggunakan latar belakang dan sumber sekaligus, yang dapat berguna untuk hal-hal seperti menampilkan bingkai di sekitar gambar utama, menggunakan hanya satu ImageView.)

  2. Anda juga harus melihat android:adjustViewBounds untuk membuat ukuran ImageView itu sendiri agar sesuai dengan gambar yang diubah ulang. Sebagai contoh, jika Anda memiliki gambar persegi panjang dalam apa yang biasanya menjadi ImageView persegi, adjustViewBounds = true akan membuatnya mengubah ukuran ImageView menjadi persegi panjang juga. Ini kemudian memengaruhi bagaimana Tampilan lain diletakkan di sekitar ImageView.

    Kemudian seperti yang ditulis Samuh, Anda dapat mengubah cara standarnya menskala gambar menggunakan android:scaleTypeparameter. Ngomong-ngomong, cara termudah untuk menemukan bagaimana ini bekerja adalah dengan sedikit bereksperimen sendiri! Hanya ingat untuk melihat tata letak di emulator itu sendiri (atau telepon yang sebenarnya) karena pratinjau di Eclipse biasanya salah.


18
Itu hal yang sama, hanya dilakukan dalam kode daripada XML. setImageBitmapadalah sama dengan android:src="..."dan setBackground...adalahandroid:background="..."
Steve Haley

4
@SuperUser juga image.setImageDrawable(...)ada android:src="..."di xml.
PureSpider

11
"android: adjustViewBounds" adalah yang berguna untuk diperhatikan! jika Anda tidak menambahkan ini, kemungkinan besar Anda akan memiliki masalah dengan batas ImageView / batas / wadah tidak scaling dengan benar.
Marah 84

2
src = vs background = adalah perbedaan bagi saya!
Christopher Rathgeb

21
android:adjustViewBoundsadalah bagian terakhir dari teka-teki saya, terima kasih!
themarketka

281

Lihat android:adjustViewBounds.

Setel ini menjadi true jika Anda ingin ImageView menyesuaikan batasnya untuk mempertahankan rasio aspek yang dapat digambar.


6
Ini adalah perbaikan yang tepat untuk masalah ini. Kami memiliki ini pada tampilan gambar kami, di mana tingginya termasuk semua spasi tambahan ini. Ini bukan "piksel transparan", karena kami memiliki fill_parent untuk lebar, dan wrap_content untuk tinggi. Jika Anda tidak memiliki adjustViewBounds = true, maka Anda mendapatkan spasi kosong tambahan. Setelah menetapkan itu menjadi kenyataan, masalah kami hilang. Terima kasih!
christophercotton

3
terima kasih, ini dan mengaturnya ke src bukannya latar belakang bekerja dengan sempurna!
Cameron


1
Ini adalah perbaikan yang sempurna untuk masalah ini. Juga untuk ukuran, gunakan wadah induk untuk mengatur ukuran, dan atur match_parent di ImageView. Ini memecahkan banyak masalah.
Nimila Hiranya

+1 untuk sampai pada intinya. Saya awalnya menulis itu dalam frasa yang lebih "sehari-hari" dan sof melarang saya mengirimkannya. Daripada mengacak-acak bulu PC pergi.
Jacksonkr

168

Kepada siapa pun yang memiliki masalah khusus ini. Anda memiliki ImageViewlebar yang Anda inginkanfill_parent dan tinggi diskalakan secara proporsional:

Tambahkan dua atribut ini ke ImageView:

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

Dan atur ImageViewlebar ke fill_parentdan tinggi kewrap_content .

Selain itu, jika Anda tidak ingin gambar Anda dipotong, coba ini:

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

16
Ya tapi gambar Anda terpotong. Solusi sempurna akan meregang ke lebar, mempertahankan rasio aspek dan tidak memotong. Saya tidak tahu mengapa ini harus dilakukan ...
Warpzit

1
Saya juga :( Maaf jika solusi saya tidak membantu Anda, tetapi itu membantu saya.
Kevin Parker

2
Kevin, apa yang Anda katakan adalah persis apa yang saya cari, jika ukuran gambar kurang dari layar, diperbesar dan dipusatkan, sempurna. Terima kasih.
Soham

1
+1, kecuali untuk "(atau lainnya View)". AFAICT tidak memiliki tampilan adjustViewBoundsatau scaleTypeatribut lainnya.
LarsH

bagaimana dengan menggunakan android: scaleType = "centerInside" alih-alih android: scaleType = "centerCrop"? Itu juga tidak akan memotong gambar tetapi memastikan bahwa lebar dan tinggi keduanya kurang dari atau sama dengan lebar dan tinggi tampilan gambar :) Ini adalah panduan visual yang bagus untuk skaletipe: thoughtbot.com/blog/android-imageview-scaletype-a-visual- panduan
vida

57

Jika Anda ingin ImageViewyang kedua skala naik dan turun sambil menjaga rasio aspek yang tepat, tambahkan ini ke XML Anda:

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

Tambahkan ini ke kode Anda:

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

Butuh beberapa saat untuk membuat ini berfungsi, tetapi ini tampaknya berfungsi dalam kedua kasus di mana gambar lebih kecil dari lebar layar dan lebih besar dari lebar layar, dan itu tidak mengotak gambar.


1
Mengapa tidak menggunakan android: scaleType = "centerCrop"?
Lukas Batteau

bekerja seperti pesona, terima kasih. scaleType tergantung pada situasi, misalnya saya membutuhkan ini.
David

Ini sedikit cara biadab untuk mengubah ukuran tampilan. Apa yang terjadi jika batas tampilan berubah setelah Anda mengatur bitmap ke ImageView? Inilah mengapa itu harus dilakukan di onMeasure (), yang dapat diimplementasikan jika Anda membuat subkelas kustom dari ImageView.
Aron Lorincz

1
Yang saya butuhkan adalah fitCenter dan AdjustViewBounds, sisa kode setidaknya untuk saya tidak perlu
kingargyle

Ini berfungsi untuk saya dan tidak perlu menambahkan kode apa pun. Tanpa AdjustViewBounds jika lebar gambar lebih kecil dari lebar imageView, itu tidak naik, sehingga tingginya berhenti ke ketinggian asli dan pada lebar beberapa band memang muncul.
Cristi Băluță

15

Ini bekerja untuk saya:

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

10

ini menyelesaikan masalah saya

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

Itu tidak mempertahankan rasio aspek gambar untuk saya.
Dmitry

9

Kode di bawah ini Berfungsi untuk gambar skala sebagai aspek rasio:

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

Lihatlah ImageView.ScaleType untuk mengontrol dan memahami cara mengubah ukuran terjadi dalam ImageView. Ketika gambar diubah ukurannya (sambil mempertahankan rasio aspeknya), kemungkinan tinggi atau lebar gambar menjadi lebih kecil dari ImageViewdimensi.


6

Gunakan properti ini di ImageView untuk menjaga rasio aspek:

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

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

Hanya jawaban ini yang membantu saya. Terima kasih!
Dmitry

6

Inilah cara kerjanya bagi saya di dalam ConstraintLayout:

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

Kemudian dalam kode, saya mengatur drawable sebagai:

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

Ini cocok dengan gambar sesuai rasio aspeknya dan membuatnya tetap di tengah.


5

Saya memiliki gambar yang lebih kecil dari layar. Untuk membuatnya membentang secara proporsional ke max dan berpusat pada tampilan saya harus menggunakan kode berikut:

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

Namun perlu diingat, bahwa jika Anda memiliki tata letak relatif dan mengatur beberapa elemen di atas atau di bawah ImageView, kemungkinan besar akan tumpang tindih dengan gambar.


4

Jika kualitas gambar menurun: gunakan

android:adjustViewBounds="true"

dari pada

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

3

Bagi Anda yang menginginkan gambar agar pas dengan tampilan gambar dengan penskalaan yang tepat dan tanpa pemangkasan digunakan

imageView.setScaleType(ScaleType.FIT_XY);

di mana imageView adalah tampilan yang mewakili ImageView Anda


4
Tidak, ini mengubah rasio aspek. Dokumen mengatakan: "Skala dalam X dan Y secara independen, sehingga src sama persis dengan dst. Ini dapat mengubah rasio aspek dari src."
Rose Perrone

Omong-omong, FIT_XY ini tidak dapat digunakan untuk mengubah lebar / tinggi gambar untuk ditampilkan pada tampilan gambar.
Bay

3

Anda dapat menghitung lebar layar. Dan Anda dapat skala 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;
    }

menghitung lebar layar dan menskalakan tinggi gambar berdasarkan lebar layar.

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

Setelah Anda bisa skala bitmap.

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

3

Saat melakukan ini secara terprogram, pastikan untuk memanggil setter dengan urutan yang benar:

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

2

Jika Anda ingin gambar Anda menempati ruang maksimum yang mungkin maka opsi terbaik adalah

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

2

Anda tidak memerlukan kode java. Anda hanya perlu:

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

Kuncinya ada di induk pertandingan untuk lebar dan tinggi


1

Coba gunakan android:layout_gravityuntuk ImageView:

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

Contoh di atas berhasil untuk saya.


1
android: layout_weight = "1" adalah kuncinya.
nima

1

Saya memiliki algoritme untuk skala bitmap untuk menyesuaikan dimensi wadah, mempertahankan rasio aspeknya. Silakan temukan solusi saya di sini

Semoga ini bisa membantu seseorang di jalan kecil!


0

Saya menggunakan ini:

<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

dalam hal menggunakan cardviewuntuk pembulatan imageviewdan diperbaiki android:layout_heightuntuk header ini bekerja untuk saya memuat gambar denganGlide

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

Anda dapat mengatur skala gambar yang juga akan mengurangi ukuran gambar Anda. Ada perpustakaan untuk itu Anda dapat mengunduh dan menggunakannya. https://github.com/niraj124124/Images-Files-scale-and-compress.git

Cara menggunakan 1) Impor kompresor-v1.0. jar ke proyek Anda. 2) Tambahkan kode sampel di bawah ini untuk diuji. ResizeLimiter resize = ImageResizer.build (); resize.scale ("inputImagePath", "outputImagePath", imageWidth, imageHeight); Banyak lagi metode yang ada sesuai dengan kebutuhan Anda


0

Lewati ImageView Anda dan berdasarkan tinggi dan lebar layar Anda dapat membuatnya

    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

Jawaban cepat:

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.