วิธีปรับขนาดภาพใน ImageView เพื่อรักษาอัตราส่วนภาพ


526

ใน Android ฉันกำหนดImageViewว่าlayout_widthจะเป็นfill_parent(ซึ่งใช้ความกว้างเต็มของโทรศัพท์)

หากภาพที่ฉันใส่ImageViewมีขนาดใหญ่กว่าlayout_widthAndroid จะปรับขนาดภาพใช่มั้ย แต่ความสูงล่ะ? เมื่อ Android ปรับขนาดภาพมันจะรักษาอัตราส่วนหรือไม่

สิ่งที่ผมพบคือว่ามีบางพื้นที่สีขาวที่ด้านบนและด้านล่างของImageViewเมื่อ Android ImageViewตาชั่งภาพที่มีขนาดใหญ่กว่าที่ มันเป็นเรื่องจริงเหรอ? ถ้าใช่ฉันจะกำจัดพื้นที่สีขาวได้อย่างไร

คำตอบ:


799
  1. ใช่โดยค่าเริ่มต้น Android จะลดขนาดภาพของคุณให้พอดีกับ ImageView เพื่อรักษาอัตราส่วนภาพ แต่ให้แน่ใจว่าคุณกำลังตั้งภาพเพื่อ ImageView โดยใช้มากกว่าandroid:src="..." ทำให้อัตราส่วนภาพรักษาสัดส่วนภาพ แต่ทำให้ขยายและบิดเบือนภาพเพื่อให้พอดีกับขนาดของ ImageView (คุณสามารถใช้พื้นหลังและแหล่งที่มาในเวลาเดียวกันซึ่งอาจมีประโยชน์สำหรับสิ่งต่าง ๆ เช่นการแสดงเฟรมรอบ ๆ ภาพหลักโดยใช้ ImageView เพียงอันเดียว)android:background="..."src=background=

  2. คุณควรเห็นandroid:adjustViewBoundsเพื่อให้ ImageView ปรับขนาดตัวเองเพื่อให้พอดีกับภาพที่ได้รับการ rescaled ตัวอย่างเช่นหากคุณมีภาพสี่เหลี่ยมในสิ่งที่ปกติจะเป็นสี่เหลี่ยม ImageView, adjustViewBounds = true จะทำให้มันปรับขนาด ImageView ให้เป็นสี่เหลี่ยมเช่นกัน จากนั้นจะมีผลต่อการจัดวางมุมมองอื่นรอบ ๆ ImageView

    จากนั้นตามที่ Samuh เขียนคุณสามารถเปลี่ยนวิธีการปรับขนาดเริ่มต้นของภาพโดยใช้android:scaleTypeพารามิเตอร์ โดยวิธีการวิธีที่ง่ายที่สุดในการค้นพบวิธีการทำงานนี้ก็คือการทดสอบตัวเองเล็กน้อย! เพียงจำไว้ว่าให้ดูที่เลย์เอาต์ในอีมูเลเตอร์ (หรือโทรศัพท์จริง) เนื่องจากภาพตัวอย่างใน Eclipse นั้นผิดปกติ


18
นั่นคือสิ่งเดียวกันเพียงทำในรหัสมากกว่า XML setImageBitmapเหมือนกับandroid:src="..."และsetBackground...เป็นandroid:background="..."
Steve Haley

4
@SuperUser image.setImageDrawable(...)อยู่android:src="..."ใน xml เช่นกัน
PureSpider

11
"android: adjustViewBounds" เป็นประโยชน์อย่างหนึ่งที่นี่เพื่อทราบ! หากคุณไม่เพิ่มสิ่งนี้คุณมีแนวโน้มมากที่สุดที่ปัญหาของกรอบ ImageView / ขอบเขต / คอนเทนเนอร์ไม่ได้ปรับขนาดอย่างถูกต้อง
โกรธ 84

2
src = vs background = เป็นความแตกต่างสำหรับฉัน!
Christopher Rathgeb

21
android:adjustViewBoundsเป็นชิ้นสุดท้ายของปริศนาของฉันขอบคุณ!
themarketka

281

android:adjustViewBoundsดู

ตั้งค่านี้เป็นจริงหากคุณต้องการให้ ImageView ปรับขอบเขตเพื่อรักษาอัตราส่วนกว้างยาวของ drawable


6
นี่คือการแก้ไขที่ถูกต้องสำหรับปัญหา เรามีสิ่งนี้ในมุมมองภาพของเราซึ่งความสูงนั้นรวมพื้นที่ว่างพิเศษทั้งหมดนี้ ไม่ใช่ "พิกเซลโปร่งใส" เนื่องจากเรามี fill_parent สำหรับความกว้างและ wrap_content สำหรับความสูง หากคุณไม่มี adjustViewBounds = true คุณจะได้รับช่องว่างพิเศษ หลังจากตั้งค่าเป็นจริงปัญหาของเราก็หายไป ขอบคุณ!
christophercotton

3
ขอบคุณนี้และการตั้งค่าเพื่อ src แทนพื้นหลังทำงานอย่างสมบูรณ์!
Cameron


1
นี่คือการแก้ไขที่สมบูรณ์แบบสำหรับปัญหา สำหรับขนาดใช้คอนเทนเนอร์พาเรนต์เพื่อกำหนดขนาดและตั้งค่า match_parent ใน ImageView วิธีนี้แก้ปัญหาได้มากมาย
Nimila Hiranya

+1 เมื่อถึงจุด ฉันเริ่มเขียนว่าในวลี "ภาษาพูด" มากขึ้นและ Sof ห้ามฉันจากการส่งมัน แทนที่จะเป็น ruffle feathers พีซีที่ใช้ไป
Jacksonkr

168

สำหรับผู้อื่นที่มีปัญหานี้โดยเฉพาะ คุณมีสิ่งImageViewที่คุณต้องการให้มีความกว้างfill_parentและความสูงตามสัดส่วน:

เพิ่มคุณสมบัติทั้งสองนี้ในImageView:

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

และการตั้งค่าImageViewความกว้างและความสูงที่จะfill_parentwrap_content

นอกจากนี้หากคุณไม่ต้องการให้ภาพของคุณถูกครอบตัดให้ลองทำดังนี้:

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

16
ใช่ แต่ภาพของคุณถูกครอบตัด โซลูชั่นที่สมบูรณ์แบบจะยืดความกว้างรักษาอัตราส่วนและไม่ครอบตัด ฉันมีความคิดว่าทำไมถึงจะต้องมีเพื่อให้ anoing ที่จะทำ ...
Warpzit

1
ฉันทั้ง :( ขออภัยหากการแก้ปัญหาของฉันไม่ได้ช่วยให้คุณ แต่มันก็ช่วยเหลือผม.
เควินปาร์คเกอร์

2
Kevin สิ่งที่คุณพูดคือสิ่งที่ฉันกำลังมองหาถ้าขนาดของภาพน้อยกว่าหน้าจอมันจะถูกซูมเข้าและอยู่กึ่งกลางที่สมบูรณ์แบบ ขอบคุณ
Soham

1
+1 ยกเว้น "(หรืออื่น ๆView)" AFAICT ไม่มีมุมมองadjustViewBoundsหรือscaleTypeคุณลักษณะอื่น
LarsH

วิธีการเกี่ยวกับการใช้ android: scaleType = "centerInside" แทนที่จะเป็น Android: scaleType = "centerCrop" มันจะไม่ครอบตัดรูปภาพ แต่ให้แน่ใจว่าทั้งความกว้างและความสูงมีค่าน้อยกว่าหรือเท่ากับความกว้างและความสูงของ imageview :) นี่เป็นคำแนะนำแบบภาพที่ดีสำหรับ scaletypes: thinkbot.com/blog/android-imageview-scaletype-a-visual- คู่มือ
vida

57

หากคุณต้องการImageViewอัตราส่วนที่เพิ่มขึ้นและลดลงในขณะที่รักษาอัตราส่วนที่เหมาะสมให้เพิ่มลงใน XML ของคุณ:

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

เพิ่มไปยังรหัสของคุณ:

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

ฉันใช้เวลาสักครู่กว่าจะได้งานนี้ แต่ดูเหมือนว่าจะใช้ได้ในทั้งสองกรณีที่ภาพมีขนาดเล็กกว่าความกว้างของหน้าจอและใหญ่กว่าความกว้างของหน้าจอและไม่ได้บรรจุภาพไว้


1
ทำไมไม่ใช้เพียง Android: scaleType = "centerCrop"
Lukas Batteau

ทำงานเหมือนจับใจขอบคุณ scaleType ขึ้นอยู่กับสถานการณ์เช่นฉันต้องการสิ่งนี้
เดวิด

นี่เป็นวิธีอนารยชนเล็กน้อยในการปรับขนาดมุมมอง จะเกิดอะไรขึ้นถ้าขอบเขตการดูเปลี่ยนแปลงหลังจากคุณตั้งค่าบิตแมปเป็น ImageView นี่คือสาเหตุที่ควรทำใน onMeasure () ซึ่งสามารถนำไปใช้ได้หากคุณสร้างคลาสย่อยที่กำหนดเองของ ImageView
Aron Lorincz

1
ฉันทั้งหมดที่จำเป็นเป็น fitCenter และ adjustViewBounds ส่วนที่เหลือของรหัสอย่างน้อยสำหรับฉันไม่จำเป็น
kingargyle

สิ่งนี้ใช้ได้สำหรับฉันและไม่จำเป็นต้องเพิ่มรหัสใด ๆ หากไม่มี widthViewBounds หากความกว้างของภาพมีขนาดเล็กกว่าความกว้างของ imageView มันจะไม่ขยายขึ้นดังนั้นความสูงจึงหยุดไปที่ความสูงดั้งเดิมและความกว้างบางแถบก็ปรากฏขึ้น
Cristi Băluță

15

สิ่งนี้ใช้ได้กับฉัน:

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


9

โค้ดด้านล่างใช้สำหรับอัตราส่วนภาพเป็นอัตราส่วน:

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

ลองดูที่ImageView.ScaleTypeImageViewควบคุมและเข้าใจวิธีการปรับขนาดที่เกิดขึ้นใน เมื่อปรับขนาดภาพ (ในขณะที่รักษาอัตราส่วนภาพไว้) โอกาสที่ความสูงหรือความกว้างของภาพจะเล็กกว่าขนาดImageViewของภาพ


6

ใช้คุณสมบัติเหล่านี้ใน ImageView เพื่อรักษาอัตราส่วน:

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

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

เฉพาะคำตอบนี้ช่วยฉัน ขอบคุณ!
มิทรี

6

นี่คือวิธีการทำงานสำหรับฉันภายในข้อ จำกัด เค้าโครง:

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

จากนั้นในรหัสฉันตั้ง drawable เป็น:

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

สิ่งนี้เหมาะกับภาพอย่างมากตามอัตราส่วนภาพและทำให้อยู่ในตำแหน่งกึ่งกลาง


5

ฉันมีภาพเล็กกว่าหน้าจอ หากต้องการให้มันขยายตามสัดส่วนให้สูงสุดและอยู่กึ่งกลางในมุมมองฉันต้องใช้รหัสต่อไปนี้:

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

โปรดจำไว้ว่าหากคุณมีเลย์เอาต์ที่สัมพันธ์กันและมีองค์ประกอบบางอย่างตั้งไว้ที่ด้านบนหรือด้านล่างของ ImageView พวกมันจะทับซ้อนกันโดยภาพ



3

สำหรับทุกคนที่คุณต้องการให้ภาพพอดีกับมุมมองภาพด้วยการปรับขนาดที่เหมาะสมและไม่มีการครอบตัด

imageView.setScaleType(ScaleType.FIT_XY);

โดยที่ imageView เป็นมุมมองที่แสดงถึง ImageView ของคุณ


4
ไม่นี่เปลี่ยนการปันส่วนมุมมอง เอกสารกล่าวว่า: "ปรับขนาดใน X และ Y อย่างอิสระดังนั้น src จึงจับคู่ dst ได้อย่างแม่นยำสิ่งนี้อาจเปลี่ยนอัตราส่วนภาพของ src"
Rose Perrone

โดยวิธีการนี้ FIT_XY ไม่สามารถใช้ในการเปลี่ยนความกว้าง / ความสูงของภาพเพื่อแสดงในมุมมองภาพ
อ่าว

3

คุณสามารถคำนวณความกว้างของหน้าจอ และคุณสามารถปรับขนาดบิตแมปได้

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

คำนวณความกว้างของหน้าจอและปรับความสูงของภาพตามความกว้างของหน้าจอ

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

หลังจากที่คุณสามารถปรับขนาดบิตแมป

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

3

เมื่อทำสิ่งนี้โดยทางโปรแกรมให้แน่ใจว่าได้เรียกตัวตั้งค่าตามลำดับที่ถูกต้อง:

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

2

หากคุณต้องการให้ภาพของคุณครอบครองพื้นที่ที่เป็นไปได้สูงสุดตัวเลือกที่ดีที่สุดก็คือ

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

2

โย่ไม่ต้องการโค้ดจาวาใด ๆ คุณเพียงแค่ต้อง:

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

คีย์อยู่ในพาเรนต์การจับคู่สำหรับความกว้างและความสูง


1

ลองใช้android:layout_gravityImageView:

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

ตัวอย่างข้างต้นทำงานให้ฉัน


1
android: layout_weight = "1" เป็นกุญแจสำคัญ
nima

1

ฉันมีอัลกอริทึมในการปรับขนาดบิตแมปเพื่อให้พอดีกับขนาดคอนเทนเนอร์โดยคงอัตราส่วนไว้ โปรดหาวิธีแก้ปัญหาของฉันที่นี่

หวังว่านี่จะช่วยให้ใครบางคนลงเลน!


0

ฉันใช้สิ่งนี้:

<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

ในกรณีที่ใช้cardviewในการปัดเศษimageviewและแก้ไขandroid:layout_heightสำหรับส่วนหัวสิ่งนี้ใช้ได้สำหรับฉันในการโหลดรูปภาพด้วยGlide

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

คุณสามารถปรับขนาดภาพที่จะลดขนาดของภาพของคุณ มีห้องสมุดให้คุณสามารถดาวน์โหลดและใช้งานได้ https://github.com/niraj124124/Images-Files-scale-and-compress.git

วิธีใช้ 1) นำเข้า compressor-v1.0 jar สำหรับโครงการของคุณ 2) เพิ่มโค้ดตัวอย่างด้านล่างเพื่อทดสอบ ResizeLimiter resize = ImageResizer.build (); resize.scale ("inputImagePath", "outputImagePath", imageWidth, imageHeight); มีวิธีการอื่น ๆ อีกมากมายตามความต้องการของคุณ


0

ผ่าน ImageView ของคุณและขึ้นอยู่กับความสูงและความกว้างของหน้าจอที่คุณสามารถทำได้

    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

คำตอบที่รวดเร็ว:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.