Cách chia tỷ lệ hình ảnh trong ImageView để giữ tỷ lệ khung hình


526

Trong Android, tôi xác định một ImageViewlayout_widthđược fill_parent(mà chiếm toàn bộ chiều rộng của điện thoại).

Nếu hình ảnh tôi đặt ImageViewlớn hơn layout_width, Android sẽ chia tỷ lệ, phải không? Nhưng còn chiều cao thì sao? Khi Android chia tỷ lệ hình ảnh, nó sẽ giữ tỷ lệ khung hình?

Những gì tôi phát hiện ra là có một số khoảng trắng ở trên cùng và dưới cùng của ImageViewAndroid khi Android chia tỷ lệ hình ảnh lớn hơn ImageView. Điều đó có đúng không? Nếu có, làm thế nào tôi có thể loại bỏ khoảng trắng đó?

Câu trả lời:


799
  1. Có, theo mặc định, Android sẽ thu nhỏ hình ảnh của bạn xuống để phù hợp với ImageView, duy trì tỷ lệ khung hình. Tuy nhiên, hãy đảm bảo bạn đang đặt hình ảnh thành ImageView bằng cách sử dụng android:src="..."chứ không phải android:background="...". src=làm cho nó chia tỷ lệ hình ảnh duy trì tỷ lệ khung hình, nhưng background=làm cho nó chia tỷ lệ làm biến dạng hình ảnh để làm cho nó phù hợp chính xác với kích thước của ImageView. (Tuy nhiên, bạn có thể sử dụng nền và nguồn cùng lúc, điều này có thể hữu ích cho những việc như hiển thị khung xung quanh ảnh chính, chỉ sử dụng một ImageView.)

  2. Bạn cũng nên xem android:adjustViewBoundsđể làm cho ImageView thay đổi kích thước để phù hợp với hình ảnh được thay đổi kích thước. Ví dụ: nếu bạn có một hình ảnh hình chữ nhật trong hình thường là ImageView hình vuông, thì điều chỉnhViewBound = true sẽ làm cho nó thay đổi kích thước ImageView thành hình chữ nhật. Điều này sau đó ảnh hưởng đến cách các Chế độ xem khác được trình bày xung quanh ImageView.

    Sau đó, như Samuh đã viết, bạn có thể thay đổi cách mặc định tỷ lệ hình ảnh bằng cách sử dụng android:scaleTypetham số. Nhân tiện, cách dễ nhất để khám phá cách thức hoạt động này chỉ đơn giản là tự mình thử nghiệm một chút! Chỉ cần nhớ nhìn vào các bố cục trong trình giả lập (hoặc một điện thoại thực tế) vì bản xem trước trong Eclipse thường sai.


18
Đó là điều tương tự, chỉ được thực hiện bằng mã chứ không phải XML. setImageBitmapcũng giống như android:src="..."setBackground...android:background="..."
Steve Haley

4
@SuperUser image.setImageDrawable(...)nằm android:src="..."trong xml.
PureSpider

11
"Android: điều chỉnhViewBound" là tiện ích cần lưu ý ở đây! nếu bạn không thêm phần này, rất có thể bạn sẽ gặp sự cố với viền / giới hạn / vùng chứa ImageView không được chia tỷ lệ chính xác.
Tức giận 84

2
src = vs nền = là sự khác biệt đối với tôi!
Christopher Rath Quay

21
android:adjustViewBoundslà mảnh ghép cuối cùng cho câu đố của tôi, cảm ơn!
themarketka

281

Xem android:adjustViewBounds.

Đặt điều này thành đúng nếu bạn muốn ImageView điều chỉnh giới hạn của nó để duy trì tỷ lệ khung hình có thể vẽ được.


6
Đây là sửa chữa chính xác cho vấn đề. Chúng tôi đã có điều này trên chế độ xem hình ảnh của chúng tôi, trong đó chiều cao bao gồm tất cả các khoảng trắng thêm này. Đó không phải là "pixel trong suốt", vì chúng tôi có fill_parent cho chiều rộng và quấn_content cho chiều cao. Nếu bạn không có điều chỉnhViewBound = true, thì bạn sẽ có thêm khoảng trắng. Sau khi đặt điều đó thành đúng, vấn đề của chúng tôi đã biến mất. Cảm ơn!
christopherc Bông

3
cảm ơn, cái này và đặt nó thành src thay vì nền hoạt động hoàn hảo!
Cameron


1
Đây là sửa chữa hoàn hảo cho vấn đề. Ngoài ra, đối với kích thước, hãy sử dụng vùng chứa chính để đặt kích thước và đặt match_parent trong ImageView. Điều này giải quyết rất nhiều rắc rối.
Nimila Hiranya

+1 để đi đến điểm. Ban đầu tôi đã viết rằng trong một cụm từ "thông tục" hơn và đã cấm tôi gửi nó. Thay vì xù lông một PC đã đi.
Jacksonkr

168

Đối với bất cứ ai khác có vấn đề đặc biệt này. Bạn có ImageViewmột chiều rộng mà bạn muốn có chiều rộng fill_parentvà chiều cao được chia tỷ lệ:

Thêm hai thuộc tính này vào ImageView:

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

Và đặt ImageViewchiều rộng fill_parentvà chiều cao thành wrap_content.

Ngoài ra, nếu bạn không muốn hình ảnh của mình bị cắt, hãy thử điều này:

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

16
Có nhưng hình ảnh của bạn bị cắt. Giải pháp hoàn hảo sẽ kéo dài theo chiều rộng, duy trì tỷ lệ khung hình và không cắt xén. Tôi không biết tại sao việc này phải được thực hiện như vậy ...
Warpzit

1
Tôi cũng vậy :( Xin lỗi nếu giải pháp của tôi không giúp được bạn, nhưng nó đã giúp tôi.
Kevin Parker

2
Kevin, những gì bạn nói là chính xác những gì tôi đang tìm kiếm, nếu kích thước của hình ảnh nhỏ hơn màn hình, nó được phóng to và căn giữa, hoàn hảo. Cảm ơn.
Soham

1
+1, ngoại trừ "(hoặc khác View)". AFAICT không có quan điểm khác có adjustViewBoundshoặc scaleTypethuộc tính.
LarsH

Làm thế nào về việc sử dụng android: scaleType = "centreInside" thay vì android: scaleType = "centreCrop"? Nó cũng sẽ không cắt hình ảnh nhưng đảm bảo rằng cả chiều rộng và chiều cao ít hơn hoặc tương đương với chiều rộng và chiều cao của ImageView :) Đây là hướng dẫn thị giác tốt cho scaletypes: thoughtbot.com/blog/android-imageview-scaletype-a-visual- hướng dẫn
vida

57

Nếu bạn muốn một ImageViewtỷ lệ cả lên và xuống trong khi vẫn giữ tỷ lệ khung hình phù hợp, hãy thêm nó vào XML của bạn:

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

Thêm mã này vào mã của bạn:

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

Tôi phải mất một thời gian để làm việc này, nhưng nó có vẻ hoạt động trong cả trường hợp hình ảnh nhỏ hơn chiều rộng màn hình và lớn hơn chiều rộng màn hình và nó không đóng hộp hình ảnh.


1
Tại sao không sử dụng android: scaleType = "centreCrop"?
Lukas Batteau

hoạt động như một sự quyến rũ, cảm ơn. scaleType tùy thuộc vào tình huống, ví dụ tôi cần chính xác điều này.
David

Đây là một cách hơi man rợ để thay đổi kích thước khung nhìn. Điều gì xảy ra nếu giới hạn lượt xem thay đổi sau khi bạn đặt bitmap thành ImageView? Đây là lý do tại sao nó nên được thực hiện trong onMeasure (), có thể được triển khai nếu bạn tạo một lớp con tùy chỉnh của ImageView.
Aron Lorincz 17/03/2016

1
Tất cả những gì tôi cần là fitCenter và điều chỉnhViewBound, phần còn lại của mã ít nhất là không cần thiết
kingargyle

Điều này làm việc cho tôi và không cần thêm bất kỳ mã nào. Nếu không có điều chỉnhViewBound nếu chiều rộng hình ảnh nhỏ hơn chiều rộng imageView, nó không tăng tỷ lệ, do đó, chiều cao dừng lại ở chiều cao tự nhiên và trên chiều rộng, một số dải xuất hiện.
Cristi Băluță

15

Điều này làm việc cho tôi:

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

10

điều này đã giải quyết vấn đề của tôi

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

Nó không giữ tỷ lệ khung hình của hình ảnh đối với tôi.
Dmitry

9

Mã bên dưới Làm việc cho tỷ lệ hình ảnh theo tỷ lệ khung hình:

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

Hãy xem ImageView.ScaleType để kiểm soát và hiểu cách thay đổi kích thước xảy ra trong một ImageView. Khi hình ảnh được thay đổi kích thước (trong khi duy trì tỷ lệ khung hình của nó), có thể là chiều cao hoặc chiều rộng của hình ảnh sẽ nhỏ hơn ImageViewkích thước của nó.


6

Sử dụng các thuộc tính này trong ImageView để giữ tỷ lệ khung hình:

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

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

Chỉ có câu trả lời này đã giúp tôi. Cảm ơn!
Dmitry

6

Đây là cách nó hoạt động với tôi trong ConstraintLayout:

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

Sau đó, trong mã, tôi đặt drawable là:

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

Điều này phù hợp với hình ảnh độc đáo theo tỷ lệ khung hình của nó và giữ nó ở trung tâm.


5

Tôi có một hình ảnh nhỏ hơn màn hình. Để nó được kéo dài theo tỷ lệ tối đa và tập trung vào khung nhìn, tôi phải sử dụng đoạn mã sau:

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

Mặc dù vậy, hãy nhớ rằng nếu bạn có bố cục tương đối và có một số yếu tố được đặt ở trên hoặc dưới ImageView, rất có thể chúng sẽ bị chồng chéo bởi hình ảnh.


4

Nếu chất lượng hình ảnh giảm trong: sử dụng

android:adjustViewBounds="true"

thay vì

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

3

Đối với bất kỳ ai trong số các bạn muốn hình ảnh phù hợp với chính xác hình ảnh với tỷ lệ phù hợp và không sử dụng cắt xén

imageView.setScaleType(ScaleType.FIT_XY);

trong đó imageView là chế độ xem đại diện cho ImageView của bạn


4
Không, điều này thay đổi khẩu phần khía cạnh. Các tài liệu nói: "Chia tỷ lệ trong X và Y một cách độc lập, sao cho src khớp chính xác với dst. Điều này có thể thay đổi tỷ lệ khung hình của src."
Hoa hồng Perrone

Nhân tiện, FIT_XY này không thể được sử dụng để thay đổi chiều rộng / chiều cao của hình ảnh để hiển thị trên hình ảnh.
Bay

3

Bạn có thể tính chiều rộng màn hình. Và bạn có thể mở rộng quy mô 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;
    }

tính chiều rộng màn hình và chiều cao hình ảnh được chia tỷ lệ theo chiều rộng màn hình.

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

Sau khi bạn có thể mở rộng quy mô bitmap.

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

3

Khi thực hiện việc này theo chương trình, hãy nhớ gọi các setters theo đúng thứ tự:

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

2

Nếu bạn muốn hình ảnh của mình chiếm không gian tối đa có thể thì tùy chọn tốt nhất sẽ là

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

2

Bạn không cần bất kỳ mã java. Bạn chỉ cần:

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

Khóa nằm trong phần khớp cha mẹ cho chiều rộng và chiều cao


1

Hãy thử sử dụng android:layout_gravitycho ImageView:

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

Ví dụ trên làm việc cho tôi.


1
android: layout_ weight = "1" là chìa khóa.
nima

1

Tôi có một thuật toán để chia tỷ lệ một bitmap để phù hợp nhất với kích thước vùng chứa, duy trì tỷ lệ khung hình của nó. Hãy tìm giải pháp của tôi ở đây

Hy vọng điều này sẽ giúp ai đó xuống làn!


0

Tôi sử dụng cái này:

<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

trong trường hợp sử dụng cardviewđể làm tròn imageviewvà cố định android:layout_heightcho tiêu đề, điều này giúp tôi tải hình ảnh vớiGlide

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

Bạn có thể chia tỷ lệ hình ảnh cũng sẽ làm giảm kích thước hình ảnh của bạn. Có một thư viện cho nó bạn có thể tải về và sử dụng nó. https://github.com/niraj124124/Images-Files-scale-and-compress.git

Cách sử dụng 1) Nhập máy nén-v1.0. jar cho dự án của bạn. 2) Thêm mã mẫu dưới đây để kiểm tra. Thay đổi kích thước thay đổi kích thước = ImageResizer.build (); resize.scale ("inputImagePath", "outputImagePath", imageWidth, imageHeight); Nhiều phương pháp khác đang có theo yêu cầu của bạn


0

Vượt qua ImageView của bạn và dựa trên chiều cao và chiều rộng màn hình, bạn có thể làm cho nó

    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

Câu trả lời nhanh:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.