ImageView में फ़िट छवि, पहलू अनुपात रखें और फिर छवि आयामों में ImageView का आकार बदलें?


164

कैसे एक यादृच्छिक आकार की एक छवि फिट करने के लिए ImageView?
कब:

  • प्रारंभ में ImageViewआयाम 250dp * 250dp हैं
  • छवि का बड़ा आयाम 250dp तक / नीचे बढ़ाया जाना चाहिए
  • छवि को अपना पहलू अनुपात रखना चाहिए
  • ImageViewआयाम स्केलिंग के बाद स्केल की गई छवि के आयामों से मेल खाना चाहिए

जैसे 100 * 150 की छवि के लिए, छवि और ImageView166 * 250 होनी चाहिए।
जैसे 150 * 100 की छवि के लिए, छवि और ImageView250 * 166 होनी चाहिए।

अगर मैं सीमा के रूप में सेट करें

<ImageView
    android:id="@+id/picture"
    android:layout_width="250dp"
    android:layout_height="250dp"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="20dp"
    android:adjustViewBounds="true" />

छवियों में ठीक से फिट है ImageView, लेकिन ImageViewहमेशा 250dp * 250dp है।


उह, क्या आपका मतलब ImageViewछवि के आकार को छवि आकार में बदलना है ? उदाहरण के लिए 100dp x 150dp की छवि ImageViewसमान मापों की होगी? या क्या आप मतलब है कि छवि को ImageViewसीमा में कैसे स्केल करें । जैसे 1000dp x 875dp की छवि को 250dp x 250dp में बढ़ाया जाएगा। क्या आपको पहलू अनुपात बनाए रखने की आवश्यकता है?
जर्नो अर्गिलेंडर

मैं चाहता हूं कि ImageView में छवि के आयाम हों, और छवि का अपना सबसे बड़ा आयाम 250dp के बराबर हो और उसका पहलू अनुपात बना रहे। उदाहरण के लिए १०० * १५० की छवि के लिए, मैं चाहता हूं कि छवि और छवि दृश्य १६६ * २५० हो। मैं अपना सवाल अपडेट करूंगा।
20:22

क्या आप किसी गतिविधि को प्रदर्शित करते समय स्केलिंग / समायोजन करना चाहते हैं (एक बार करें) या जब गतिविधि पर कुछ कर रहे हों जैसे कि गैलरी / वेब से चित्र का चयन करना (कई बार करें लेकिन लोड पर नहीं) या दोनों?
जर्नो अर्गिलेंडर

मेरा संशोधित उत्तर देखें, जो जैसा आप चाहते हैं वैसा ही करना चाहिए :)
जारनो अर्गिलेंडर

जवाबों:


137

(मूल प्रश्न के स्पष्टीकरण के बाद उत्तर को भारी रूप से संशोधित किया गया था)

स्पष्टीकरण के बाद:
यह केवल xml में नहीं किया जा सकता है । छवि को स्केल करना संभव नहीं है और ImageViewइसलिए छवि का एक आयाम हमेशा 250dp ImageViewहोगा और छवि के समान आयाम होंगे।

इस कोड को तराजू Drawable एक के ImageViewएक आयाम बिल्कुल 250dp और पहलू अनुपात रखने के साथ 250dp एक्स 250dp की तरह एक वर्ग में रहने के लिए। फिर ImageViewस्केल की गई छवि के आयामों का मिलान करने के लिए आकार परिवर्तन किया जाता है। एक गतिविधि में कोड का उपयोग किया जाता है। मैंने बटन क्लिक हैंडलर के माध्यम से इसका परीक्षण किया।

का आनंद लें। :)

private void scaleImage(ImageView view) throws NoSuchElementException  {
    // Get bitmap from the the ImageView.
    Bitmap bitmap = null;

    try {
        Drawable drawing = view.getDrawable();
        bitmap = ((BitmapDrawable) drawing).getBitmap();
    } catch (NullPointerException e) {
        throw new NoSuchElementException("No drawable on given view");
    } catch (ClassCastException e) {
        // Check bitmap is Ion drawable
        bitmap = Ion.with(view).getBitmap();
    }

    // Get current dimensions AND the desired bounding box
    int width = 0;

    try {
        width = bitmap.getWidth();
    } catch (NullPointerException e) {
        throw new NoSuchElementException("Can't find bitmap on given view/drawable");
    }

    int height = bitmap.getHeight();
    int bounding = dpToPx(250);
    Log.i("Test", "original width = " + Integer.toString(width));
    Log.i("Test", "original height = " + Integer.toString(height));
    Log.i("Test", "bounding = " + Integer.toString(bounding));

    // Determine how much to scale: the dimension requiring less scaling is
    // closer to the its side. This way the image always stays inside your
    // bounding box AND either x/y axis touches it.  
    float xScale = ((float) bounding) / width;
    float yScale = ((float) bounding) / height;
    float scale = (xScale <= yScale) ? xScale : yScale;
    Log.i("Test", "xScale = " + Float.toString(xScale));
    Log.i("Test", "yScale = " + Float.toString(yScale));
    Log.i("Test", "scale = " + Float.toString(scale));

    // Create a matrix for the scaling and add the scaling data
    Matrix matrix = new Matrix();
    matrix.postScale(scale, scale);

    // Create a new bitmap and convert it to a format understood by the ImageView 
    Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
    width = scaledBitmap.getWidth(); // re-use
    height = scaledBitmap.getHeight(); // re-use
    BitmapDrawable result = new BitmapDrawable(scaledBitmap);
    Log.i("Test", "scaled width = " + Integer.toString(width));
    Log.i("Test", "scaled height = " + Integer.toString(height));

    // Apply the scaled bitmap
    view.setImageDrawable(result);

    // Now change ImageView's dimensions to match the scaled image
    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams(); 
    params.width = width;
    params.height = height;
    view.setLayoutParams(params);

    Log.i("Test", "done");
}

private int dpToPx(int dp) {
    float density = getApplicationContext().getResources().getDisplayMetrics().density;
    return Math.round((float)dp * density);
}

के लिए xml कोड ImageView:

<ImageView a:id="@+id/image_box"
    a:background="#ff0000"
    a:src="@drawable/star"
    a:layout_width="wrap_content"
    a:layout_height="wrap_content"
    a:layout_marginTop="20dp"
    a:layout_gravity="center_horizontal"/>


स्केलिंग कोड के लिए इस चर्चा के लिए धन्यवाद:
http://www.anddev.org/resize_and_rotate_image_-_example-t621.html


अद्यतन 7 नवंबर, 2012:
टिप्पणियों में सुझाए अनुसार अशक्त सूचक चेक जोड़ा गया


1
ImageView हमेशा 250 * 250 होगा।
जूल

2
ठीक। यह केवल xml में नहीं किया जा सकता है। जावा कोड की आवश्यकता है। Xml से आप या तो छवि को माप सकते हैं या ImageViewदोनों को नहीं।
जारनो अर्गिलेंडर

93
एहसास नहीं हुआ कि आप android को बदल सकते हैं: a:
StackOverflowed

2
आयन अतुल्यकालिक नेटवर्किंग और छवि लोड करने के लिए एक ढाँचा है: github.com/koush/ion
थॉमस

1
जावा अत्यंत बदसूरत भाषा है क्योंकि इसे ऐसे सरल कार्यों के लिए बहुत सारे कोड लिखने की आवश्यकता होती है।
दिमित्री

245

इस विशिष्ट प्रश्न का उत्तर नहीं दिया जा सकता है, लेकिन यदि कोई है, तो मेरी तरह, जवाब की खोज करने के लिए ImageView को बाउंड साइज के साथ कैसे फिट करें (उदाहरण के लिए maxWidth) , पहलू अनुपात को संरक्षित करते हुए और फिर ImageView द्वारा कब्जा किए गए अत्यधिक स्थान से छुटकारा पाएं, फिर सबसे सरल उपाय XML में निम्नलिखित गुणों का उपयोग करना है:

    android:scaleType="centerInside"
    android:adjustViewBounds="true"

13
यदि आप छवि को छोटा नहीं करना चाहते हैं तो यह काम करता है।
Janusz

मैं इसे कैसे बढ़ाऊँ अगर इसका बहुत छोटा और पहलू अनुपात भी बना रहे?
कौस्तुभ भागवत

अगर किसी को जरूरत है, "fitCenter" स्केलटेप के लिए एक और विशेषता है, और यह छवि को स्केल नहीं करेगा, लेकिन किसी भी बड़ी छवि के लिए, यह पहलू अनुपात बनाए रखने वाले व्यू बॉक्स के अंदर छवि के अधिकतम आकार को फिट करेगा
योगेश प्रजापति

छोटे चित्रों को स्केल करने के लिए इसके बजाय स्केल टाइप = "सेंटरक्रॉप" का उपयोग करें।
ईवाब

इस समाधान के साथ काम करने के लिए मेरे लिए एक और बात "एंड्रॉइड: src" का उपयोग करना है न कि मेरी छवि को परिष्कृत करने के लिए "एंड्रॉइड: बैकग्राउंड"।
कोडिंगपैन

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

23

नीचे दिए गए कोड बिटमैप को छवि के समान आकार के साथ पूरी तरह से बनाते हैं। बिटमैप छवि की ऊंचाई और चौड़ाई प्राप्त करें और फिर इमेजव्यू के मापदंडों की मदद से नई ऊंचाई और चौड़ाई की गणना करें। जो आपको आवश्यक पहलू अनुपात के साथ आवश्यक छवि प्रदान करते हैं।

int currentBitmapWidth = bitMap.getWidth();
int currentBitmapHeight = bitMap.getHeight();

int ivWidth = imageView.getWidth();
int ivHeight = imageView.getHeight();
int newWidth = ivWidth;

newHeight = (int) Math.floor((double) currentBitmapHeight *( (double) new_width / (double) currentBitmapWidth));

Bitmap newbitMap = Bitmap.createScaledBitmap(bitMap, newWidth, newHeight, true);

imageView.setImageBitmap(newbitMap)

का आनंद लें।


3
यह मूल ऊंचाई को उसी कारक से कम कर देगा जिसके द्वारा चौड़ाई कम हो गई थी। यह उस नए हेट को प्रभावित नहीं करेगा। आदर्श रूप से आपको जांचना चाहिए कि कौन सा अनुपात बड़ा है (currentBitmapHeight / ivHeight, currentBitmapWidth / ivWidth) और फिर इसके आधार पर आगे का निर्णय लेते हैं।
सुमित त्रेहन

1
यह वास्तव में पूरी तरह से काम करता है, हालांकि आपको ivHeight या newWidth की आवश्यकता नहीं है, बस ivWidth को गणना में डाल दें।
स्टुअर्ट

14

android:scaleType="fitXY"अपने को जोड़ने का प्रयास करें ImageView


5
यदि मूल छवि को चुकता नहीं किया जाता है तो यह पहलू अनुपात को संशोधित करेगा।
जूल

1
fitXYलगभग हमेशा छवि के पहलू अनुपात को बदल देगा। ओपी स्पष्ट रूप से उल्लेख करता है कि पहलू अनुपात को बनाए रखा जाना चाहिए।
इस्सीफ्लेम

7

एक दिन की खोज के बाद, मुझे लगता है कि यह सबसे आसान उपाय है:

imageView.getLayoutParams().width = 250;
imageView.getLayoutParams().height = 250;
imageView.setAdjustViewBounds(true);

2
आपके अच्छे उत्तर के लिए धन्यवाद, लेकिन मुझे लगता है कि adjustViewBoundsXML

7

सबसे अच्छा समाधान जो ज्यादातर मामलों में काम करता है

यहाँ एक उदाहरण है:

<ImageView android:id="@+id/avatar"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:scaleType="fitXY"/>

1
पदावनत एपीआई (फिल_परेंट) पर भरोसा न करें
fdermishin

यह ओपी के सवाल का जवाब कैसे देता है। यह एस्पेट अनुपात को बनाए नहीं रखेगा
एलेक्स

6

यह सब XML का उपयोग करके किया जा सकता है ... अन्य तरीके बहुत जटिल लगते हैं। वैसे भी, आप केवल ऊँचाई सेट करते हैं जो आप कभी भी डीपी में चाहते हैं, फिर सामग्री या वीज़ा वर्सा को लपेटने के लिए चौड़ाई सेट करें। छवि के आकार को समायोजित करने के लिए बड़े पैमाने पर फ़िटकेंटर का उपयोग करें।

<ImageView
    android:layout_height="200dp"
    android:layout_width="wrap_content"
    android:scaleType="fitCenter"
    android:adjustViewBounds="true"
    android:src="@mipmap/ic_launcher"
    android:layout_below="@+id/title"
    android:layout_margin="5dip"
    android:id="@+id/imageView1">

4

इस कोड का उपयोग करें:

<ImageView android:id="@+id/avatar"
           android:layout_width="fill_parent"
           android:layout_height="match_parent"
           android:scaleType="fitXY" />

4

संपादित जर्नो आर्गिलैंडर्स का जवाब:

अपनी चौड़ाई और ऊँचाई के साथ छवि को कैसे फिट करें:

1) प्रारंभिक छवि देखें और सेट करें:

iv = (ImageView) findViewById(R.id.iv_image);
iv.setImageBitmap(image);

2) अब आकार:

scaleImage(iv);

संपादित scaleImageविधि: ( आप विस्तारित सीमा मानों को बदल सकते हैं )

private void scaleImage(ImageView view) {
    Drawable drawing = view.getDrawable();
    if (drawing == null) {
        return;
    }
    Bitmap bitmap = ((BitmapDrawable) drawing).getBitmap();

    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    int xBounding = ((View) view.getParent()).getWidth();//EXPECTED WIDTH
    int yBounding = ((View) view.getParent()).getHeight();//EXPECTED HEIGHT

    float xScale = ((float) xBounding) / width;
    float yScale = ((float) yBounding) / height;

    Matrix matrix = new Matrix();
    matrix.postScale(xScale, yScale);

    Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
    width = scaledBitmap.getWidth();
    height = scaledBitmap.getHeight();
    BitmapDrawable result = new BitmapDrawable(context.getResources(), scaledBitmap);

    view.setImageDrawable(result);

    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams(); 
    params.width = width;
    params.height = height;
    view.setLayoutParams(params);
}

और .xml:

<ImageView
    android:id="@+id/iv_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal" />

मुझे लगता है कि यह कलाकार: LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams (); दूसरे रास्ते पर जाना चाहिए, क्योंकि MarginLayoutParams ViewGroup.LayoutParams से विरासत में मिला है।
जय जैकब्स

3

यह मेरे मामले के लिए किया था।

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

2

अगर यह आपके लिए काम नहीं कर रहा है, तो एंड्रॉइड को बदलें: एंड्रॉइड के साथ पृष्ठभूमि: src

android: src प्रमुख चाल चलेगा

    <ImageView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:scaleType="fitCenter"
    android:src="@drawable/bg_hc" />

यह एक आकर्षण की तरह ठीक काम कर रहा है

यहां छवि विवरण दर्ज करें


1

मुझे एक ImageView और एक बिटमैप की आवश्यकता है, इसलिए Bitmap को ImageView आकार में स्केल किया जाता है, और ImageView का आकार स्केल्ड बिटमैप के समान है :)।

मैं इस पोस्ट के माध्यम से देख रहा था कि यह कैसे करना है, और आखिरकार मुझे क्या चाहिए, हालांकि यहां वर्णित तरीका नहीं है।

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/acpt_frag_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/imageBackground"
android:orientation="vertical">

<ImageView
    android:id="@+id/acpt_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:adjustViewBounds="true"
    android:layout_margin="@dimen/document_editor_image_margin"
    android:background="@color/imageBackground"
    android:elevation="@dimen/document_image_elevation" />

और फिर onCreateView मेथड में

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_scanner_acpt, null);

    progress = view.findViewById(R.id.progress);

    imageView = view.findViewById(R.id.acpt_image);
    imageView.setImageBitmap( bitmap );

    imageView.getViewTreeObserver().addOnGlobalLayoutListener(()->
        layoutImageView()
    );

    return view;
}

और फिर layoutImageView () कोड

private void layoutImageView(){

    float[] matrixv = new float[ 9 ];

    imageView.getImageMatrix().getValues(matrixv);

    int w = (int) ( matrixv[Matrix.MSCALE_X] * bitmap.getWidth() );
    int h = (int) ( matrixv[Matrix.MSCALE_Y] * bitmap.getHeight() );

    imageView.setMaxHeight(h);
    imageView.setMaxWidth(w);

}

और परिणाम यह है कि छवि पूरी तरह से अंदर फिट होती है, पहलू अनुपात रखते हुए, और बिटमैप के अंदर होने पर ImageView से अतिरिक्त बचे हुए पिक्सेल नहीं होते हैं।

परिणाम

यह महत्वपूर्ण है ImageView का मतलब यह है कि wra_content और AdjustViewBounds सच है, फिर setMaxWidth और setMaxHeight काम करेगा, यह ImageView के स्रोत कोड में लिखा गया है

/*An optional argument to supply a maximum height for this view. Only valid if
 * {@link #setAdjustViewBounds(boolean)} has been set to true. To set an image to be a
 * maximum of 100 x 100 while preserving the original aspect ratio, do the following: 1) set
 * adjustViewBounds to true 2) set maxWidth and maxHeight to 100 3) set the height and width
 * layout params to WRAP_CONTENT. */

0

मुझे पिकासो के साथ एक बाधा लेआउट में ऐसा करने की आवश्यकता थी, इसलिए मैंने ऊपर दिए गए कुछ उत्तरों को एक साथ जोड़ दिया और इस समाधान के साथ आया (मुझे पहले से पता है कि मैं जिस छवि को लोड कर रहा हूं उसका पहलू अनुपात जानता हूं, ताकि मदद मिले):

SetContentView (...) के बाद कहीं मेरी गतिविधि कोड में कॉल किया गया

protected void setBoxshotBackgroundImage() {
    ImageView backgroundImageView = (ImageView) findViewById(R.id.background_image_view);

    if(backgroundImageView != null) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int width = displayMetrics.widthPixels;
        int height = (int) Math.round(width * ImageLoader.BOXART_HEIGHT_ASPECT_RATIO);

        // we adjust the height of this element, as the width is already pinned to the parent in xml
        backgroundImageView.getLayoutParams().height = height;

        // implement your Picasso loading code here
    } else {
        // fallback if no element in layout...
    }
}

मेरे XML में

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteY="0dp"
tools:layout_editor_absoluteX="0dp">

    <ImageView
        android:id="@+id/background_image_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="fitStart"
        app:srcCompat="@color/background"
        android:adjustViewBounds="true"
        tools:layout_editor_absoluteY="0dp"
        android:layout_marginTop="0dp"
        android:layout_marginBottom="0dp"
        android:layout_marginRight="0dp"
        android:layout_marginLeft="0dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <!-- other elements of this layout here... -->

</android.support.constraint.ConstraintLayout>

एक कमी की कमी पर ध्यान दें Bottom_toBottomOf विशेषता। ImageLoader इमेज लोडिंग उपयोग विधियों और स्थिरांक के लिए मेरा अपना स्थिर वर्ग है।


0

मैं एक बहुत ही सरल समाधान का उपयोग कर रहा हूं। यहाँ मेरा कोड:

imageView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.getLayoutParams().height = imageView.getLayoutParams().width;
imageView.setMinimumHeight(imageView.getLayoutParams().width);

मेरे चित्रों को गतिशील रूप से ग्रिडव्यू में जोड़ा जाता है। जब आप इन सेटिंग्स को इमेजव्यू बनाते हैं, तो चित्र 1: 1 अनुपात में स्वचालित रूप से प्रदर्शित हो सकता है।


0

छवि को आकार देने के लिए सरल गणित का उपयोग करें। या तो आप आकार बदल सकते हैं ImageViewया आप सेट की तुलना में ड्रा करने योग्य छवि का आकार बदल सकते हैं ImageView। अपने बिटमैप की चौड़ाई और ऊँचाई ज्ञात करें जिसे आप सेट करना चाहते हैं ImageViewऔर वांछित विधि को कॉल करते हैं। मान लीजिए कि आपकी चौड़ाई 500 कॉल विधि की तुलना में ऊंचाई से अधिक है

//250 is the width you want after resize bitmap
Bitmat bmp = BitmapScaler.scaleToFitWidth(bitmap, 250) ;
ImageView image = (ImageView) findViewById(R.id.picture);
image.setImageBitmap(bmp);

आप बिटमैप के आकार के लिए इस वर्ग का उपयोग करें।

public class BitmapScaler{
// Scale and maintain aspect ratio given a desired width
// BitmapScaler.scaleToFitWidth(bitmap, 100);
 public static Bitmap scaleToFitWidth(Bitmap b, int width)
  {
    float factor = width / (float) b.getWidth();
    return Bitmap.createScaledBitmap(b, width, (int) (b.getHeight() * factor), true);
  }


  // Scale and maintain aspect ratio given a desired height
  // BitmapScaler.scaleToFitHeight(bitmap, 100);
  public static Bitmap scaleToFitHeight(Bitmap b, int height)
  {
    float factor = height / (float) b.getHeight();
    return Bitmap.createScaledBitmap(b, (int) (b.getWidth() * factor), height, true);
   }
 }

xml कोड है

<ImageView
android:id="@+id/picture"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:adjustViewBounds="true"
android:scaleType="fitcenter" />

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" />
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.