ImageView स्केलिंग TOP_CROP


88

मेरे पास ImageViewएक पिंग प्रदर्शित है जिसमें डिवाइस की तुलना में एक बड़ा पहलू अनुपात है (खड़ी बोली - इसका अर्थ है)। मैं पहलू अनुपात को बनाए रखते हुए इसे प्रदर्शित करना चाहता हूं, माता-पिता की चौड़ाई से मेल खाता है, और छवि को स्क्रीन के शीर्ष पर पिन कर रहा है।

CENTER_CROPस्केल प्रकार के रूप में उपयोग करने के साथ मुझे जो समस्या है वह यह है कि यह (समझ में आने वाली) छवि को देखने के लिए ऊपरी किनारे को शीर्ष किनारे पर संरेखित करने के बजाय स्केल की गई छवि को केंद्र में रखेगा।

इसके साथ समस्या FIT_STARTयह है कि छवि स्क्रीन ऊंचाई पर फिट होगी और चौड़ाई नहीं भरेगी।

मैंने एक कस्टम ImageView onDraw(Canvas)का उपयोग करके और कैनवास का उपयोग करके मैन्युअल रूप से इसे ओवरराइडिंग और हैंडल करके इस समस्या को हल किया है ; इस दृष्टिकोण के साथ समस्या यह है कि 1) मुझे चिंता है कि एक सरल समाधान हो सकता है, 2) मुझे super(AttributeSet)कंस्ट्रक्टर में कॉल करते समय एक वीएम मेम अपवाद मिल रहा है जब 330kb का एक src img सेट करने की कोशिश कर रहा है जब ढेर 3 mb मुक्त है (6 एमबी के ढेर के आकार के साथ) और खिचड़ी भाषा क्यों बाहर काम करती है।

किसी भी विचार / सुझाव / समाधान बहुत स्वागत है :)

धन्यवाद

ps मुझे लगा कि एक समाधान एक मैट्रिक्स स्केल प्रकार का उपयोग करना और इसे स्वयं करना हो सकता है, लेकिन यह मेरे वर्तमान समाधान की तुलना में एक ही या अधिक काम करने वाला लगता है!


1
क्या आपने CENTER_CROP के साथ प्रयास किया और ImageView के साथ एडजस्टेबल व्यूज प्रॉपर्टी को सही माना?
प्रवीण जीजी

2
हाँ, मैंने कोशिश की है कि thx, कोई भी सफलता im डर नहीं है क्योंकि यह दृश्य का विस्तार करेगा जब तक कि यह अपने माता-पिता को चौड़ा न कर दे, जो स्क्रीन से बड़ा नहीं होगा, और फिर स्क्रीन पर छवि को अतिरिक्त ऊंचाई / 2 से ऊपर की ओर पोकिंग करें और नीचे
डोरी

जवाबों:


84

ठीक है, मेरे पास काम करने का हल है। डार्को के संकेत ने मुझे ImageView वर्ग (धन्यवाद) को फिर से देखा और एक मैट्रिक्स का उपयोग करके परिवर्तन को लागू किया (जैसा कि मुझे मूल रूप से संदेह था लेकिन मेरे पहले प्रयास में सफलता नहीं मिली!)। मेरे कस्टम इमेज व्यू वर्ग में मैं कंस्ट्रक्टर के setScaleType(ScaleType.MATRIX)बाद कॉल करता हूं super(), और निम्न विधि है।

    @Override
    protected boolean setFrame(int l, int t, int r, int b)
    {
        Matrix matrix = getImageMatrix(); 
        float scaleFactor = getWidth()/(float)getDrawable().getIntrinsicWidth();    
        matrix.setScale(scaleFactor, scaleFactor, 0, 0);
        setImageMatrix(matrix);
        return super.setFrame(l, t, r, b);
    }

मैंने इस setFrame()विधि में int को रखा है जैसे कि ImageView में कॉल configureBounds()इस पद्धति के भीतर है, जो कि सभी स्केलिंग और मैट्रिक्स का सामान होता है, इसलिए मुझे तर्कसंगत लगता है (यदि आप असहमत हैं तो कहें)

नीचे AOSP से सुपर.सेटफ्रेम () विधि है

 @Override
    protected boolean setFrame(int l, int t, int r, int b) {
        boolean changed = super.setFrame(l, t, r, b);
        mHaveFrame = true;
        configureBounds();
        return changed;
    }

यहाँ पूर्ण वर्ग src खोजें


कोड के लिए धन्यवाद, @doridori! यह ठीक काम किया! मुझे समझ में नहीं आ रहा है कि आपने अपने स्पष्टीकरण में "सेटफ्रैम" विधि क्यों दोहराई ... मैंने सफलता के साथ सिर्फ पहला प्रयोग किया (और दूसरे xD को पूरी तरह से नजरअंदाज कर दिया)
Alesqui

3
दो घंटे के लिए xml लेआउट के माध्यम से इससे लड़ने के बाद, यह काम किया। काश मैं तुम्हें और अधिक नावों दे सकता।
मार्क बीटन

5
मैं सुपर () कॉल करने के लिए पहले शरीर अन्यथा छवि के बिना एक रीपेंट प्रदर्शित नहीं होता था
sherpya

1
@VitorHugoSchwaab में आपको मैट्रिक्स की तरह थम्स का उपयोग करना है। पोस्ट ट्रॉल्स्लेट (..)
एंटोन

1
पृष्ठभूमि का उपयोग नहीं कर सकते? केवल src का उपयोग करें?
जांग

43

यहाँ नीचे में इसे केंद्रित करने के लिए मेरा कोड है। Btw। डोरी के कोड में एक छोटा सा बग है: चूंकि super.frame()इसे बहुत अंत में कहा जाता है, इसलिए getWidth()विधि गलत मान लौटा सकती है। यदि आप इसे शीर्ष पर केन्द्रित करना चाहते हैं तो पोस्टट्रांसलेट लाइन को हटा दें और आपका काम पूरा हो जाएगा। अच्छी बात यह है कि इस कोड के साथ आप इसे कहीं भी ले जा सकते हैं। (सही, केंद्र => कोई समस्या नहीं;)

    public class CenterBottomImageView extends ImageView {

        public CenterBottomImageView(Context context) {
            super(context);
            setup();
        }

        public CenterBottomImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
            setup();
        }

        public CenterBottomImageView(Context context, AttributeSet attrs,
                int defStyle) {
            super(context, attrs, defStyle);
            setup();
        }

        private void setup() {
            setScaleType(ScaleType.MATRIX);
        }

        @Override
        protected boolean setFrame(int frameLeft, int frameTop, int frameRight, int frameBottom) {
            if (getDrawable() == null) {
                return super.setFrame(frameLeft, frameTop, frameRight, frameBottom);
            }
            float frameWidth = frameRight - frameLeft;
            float frameHeight = frameBottom - frameTop;

            float originalImageWidth = (float)getDrawable().getIntrinsicWidth();
            float originalImageHeight = (float)getDrawable().getIntrinsicHeight();

            float usedScaleFactor = 1;

            if((frameWidth > originalImageWidth) || (frameHeight > originalImageHeight)) {
                // If frame is bigger than image
                // => Crop it, keep aspect ratio and position it at the bottom and center horizontally

                float fitHorizontallyScaleFactor = frameWidth/originalImageWidth;
                float fitVerticallyScaleFactor = frameHeight/originalImageHeight;

                usedScaleFactor = Math.max(fitHorizontallyScaleFactor, fitVerticallyScaleFactor);
            }

            float newImageWidth = originalImageWidth * usedScaleFactor;
            float newImageHeight = originalImageHeight * usedScaleFactor;

            Matrix matrix = getImageMatrix();
            matrix.setScale(usedScaleFactor, usedScaleFactor, 0, 0); // Replaces the old matrix completly
//comment matrix.postTranslate if you want crop from TOP
            matrix.postTranslate((frameWidth - newImageWidth) /2, frameHeight - newImageHeight);
            setImageMatrix(matrix);
            return super.setFrame(frameLeft, frameTop, frameRight, frameBottom);
        }

    }

बढ़िया, बग को इंगित करने के लिए धन्यवाद। मैंने थोड़ी देर के लिए इस कोड को नहीं छुआ है, इसलिए यह एक बेवकूफी भरा सुझाव हो सकता है लेकिन सेटविड बग को ठीक करने के लिए आप इंगित कर सकते हैं कि कोई (r-l)इसके बजाय उपयोग नहीं कर सकता है ?
डोरी

निश्चित रूप से लाइन if((frameWidth > originalImageWidth) || (frameHeight > originalImageHeight))उलट होनी चाहिए? दूसरे शब्दों में, क्या आपको परीक्षण नहीं करना चाहिए कि क्या छवि फ्रेम से बड़ी है? मैं इसके साथ प्रतिस्थापित करने का सुझाव देता हूंif((originalImageWidth > frameWidth ) || (originalImageHeight > frameHeight ))
कार्लोस पी

मैंने जब से माता-पिता की चौड़ाई का उपयोग ((View) getParent()).getWidth()किया है, ImageViewवहMATCH_PARENT
sherpya

@ जय यह बहुत अच्छा काम करता है। Im onLayout () विधि में मैट्रिक्स कम्प्यूटिंग बना रहा है, जिसे रोटेशन पर भी बुलाया जाता है, जहां सेटफ़्रेम नहीं होता है।
बॉक्स

इसके लिए धन्यवाद, पूरी तरह से काम करता है, और यह भी जल्दी से नीचे की फसल को शीर्ष फसल में बदलने का एक तरीका देने के लिए धन्यवाद 1 कोड की लाइन
मूनब्लूम

39

TOP_CROPकार्यक्षमता प्राप्त करने के लिए आपको एक कस्टम छवि दृश्य लिखने की आवश्यकता नहीं है । तुम बस संशोधित करने की आवश्यकता matrixकी ImageView

  1. सेट scaleTypeकरने के लिए matrixके लिए ImageView:

    <ImageView
          android:id="@+id/imageView"
          android:contentDescription="Image"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:src="@drawable/image"
          android:scaleType="matrix"/>
    
  2. इसके लिए एक कस्टम मैट्रिक्स सेट करें ImageView:

    final ImageView imageView = (ImageView) findViewById(R.id.imageView);
    final Matrix matrix = imageView.getImageMatrix();
    final float imageWidth = imageView.getDrawable().getIntrinsicWidth();
    final int screenWidth = getResources().getDisplayMetrics().widthPixels;
    final float scaleRatio = screenWidth / imageWidth;
    matrix.postScale(scaleRatio, scaleRatio);
    imageView.setImageMatrix(matrix);
    

ऐसा करने से आपको TOP_CROPकार्यक्षमता मिलेगी ।


2
इसने मेरे लिए काम किया। हालाँकि, मुझे पैमाना की जाँच करनी है अगर यह <1 I है तो बस बदल scaleTypeदें centerCropअन्यथा मैं किनारों पर रिक्त स्थान देखूँगा।
अरस्त

उन मामलों के लिए यह काम कैसे करें जहां नीचे की संरेखित छवियों की आवश्यकता है?
सागर

26

यह उदाहरण उन चित्रों के साथ काम करता है जो ऑब्जेक्ट + कुछ अनुकूलन के निर्माण के बाद लोड किए गए हैं। मैंने कोड में कुछ टिप्पणियां जोड़ीं जो बताती हैं कि क्या चल रहा है।

कॉल करने के लिए याद रखें:

imageView.setScaleType(ImageView.ScaleType.MATRIX);

या

android:scaleType="matrix"

जावा स्रोत:

import com.appunite.imageview.OverlayImageView;

public class TopAlignedImageView extends ImageView {
    private Matrix mMatrix;
    private boolean mHasFrame;

    @SuppressWarnings("UnusedDeclaration")
    public TopAlignedImageView(Context context) {
        this(context, null, 0);
    }

    @SuppressWarnings("UnusedDeclaration")
    public TopAlignedImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    @SuppressWarnings("UnusedDeclaration")
    public TopAlignedImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mHasFrame = false;
        mMatrix = new Matrix();
        // we have to use own matrix because:
        // ImageView.setImageMatrix(Matrix matrix) will not call
        // configureBounds(); invalidate(); because we will operate on ImageView object
    }

    @Override
    protected boolean setFrame(int l, int t, int r, int b)
    {
        boolean changed = super.setFrame(l, t, r, b);
        if (changed) {
            mHasFrame = true;
            // we do not want to call this method if nothing changed
            setupScaleMatrix(r-l, b-t);
        }
        return changed;
    }

    private void setupScaleMatrix(int width, int height) {
        if (!mHasFrame) {
            // we have to ensure that we already have frame
            // called and have width and height
            return;
        }
        final Drawable drawable = getDrawable();
        if (drawable == null) {
            // we have to check if drawable is null because
            // when not initialized at startup drawable we can
            // rise NullPointerException
            return;
        }
        Matrix matrix = mMatrix;
        final int intrinsicWidth = drawable.getIntrinsicWidth();
        final int intrinsicHeight = drawable.getIntrinsicHeight();

        float factorWidth = width/(float) intrinsicWidth;
        float factorHeight = height/(float) intrinsicHeight;
        float factor = Math.max(factorHeight, factorWidth);

        // there magic happen and can be adjusted to current
        // needs
        matrix.setTranslate(-intrinsicWidth/2.0f, 0);
        matrix.postScale(factor, factor, 0, 0);
        matrix.postTranslate(width/2.0f, 0);
        setImageMatrix(matrix);
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        super.setImageDrawable(drawable);
        // We have to recalculate image after chaning image
        setupScaleMatrix(getWidth(), getHeight());
    }

    @Override
    public void setImageResource(int resId) {
        super.setImageResource(resId);
        // We have to recalculate image after chaning image
        setupScaleMatrix(getWidth(), getHeight());
    }

    @Override
    public void setImageURI(Uri uri) {
        super.setImageURI(uri);
        // We have to recalculate image after chaning image
        setupScaleMatrix(getWidth(), getHeight());
    }

    // We do not have to overide setImageBitmap because it calls 
    // setImageDrawable method

}

उन मामलों के लिए यह काम कैसे करें जहां नीचे की संरेखित छवियों की आवश्यकता है?
सागर

13

डोरी पर आधारित मैं एक ऐसे समाधान का उपयोग कर रहा हूं जो या तो छवि को चौड़ाई या ऊंचाई के आधार पर छवि को हमेशा आसपास के कंटेनर को भरने के लिए उपयोग करता है। यह केंद्र के बजाय मूल (CENTER_CROP) के बजाय छवि के शीर्ष बाएं बिंदु का उपयोग करके पूरे उपलब्ध स्थान को भरने के लिए एक छवि को स्केल करने की अनुमति देता है :

@Override
protected boolean setFrame(int l, int t, int r, int b)
{

    Matrix matrix = getImageMatrix(); 
    float scaleFactor, scaleFactorWidth, scaleFactorHeight;
    scaleFactorWidth = (float)width/(float)getDrawable().getIntrinsicWidth();
    scaleFactorHeight = (float)height/(float)getDrawable().getIntrinsicHeight();    

    if(scaleFactorHeight > scaleFactorWidth) {
        scaleFactor = scaleFactorHeight;
    } else {
        scaleFactor = scaleFactorWidth;
    }

    matrix.setScale(scaleFactor, scaleFactor, 0, 0);
    setImageMatrix(matrix);

    return super.setFrame(l, t, r, b);
}

मुझे उम्मीद है कि यह मदद करता है - मेरी परियोजना में एक इलाज की तरह काम करता है।


11
यह बेहतर उपाय है ... और जोड़ें: फ्लोट चौड़ाई = आर - एल; फ्लोट ऊंचाई = बी - टी;
गेलट्रूड

9

इनमें से किसी भी समाधान ने मेरे लिए काम नहीं किया, क्योंकि मैं एक वर्ग चाहता था जो क्षैतिज या ऊर्ध्वाधर दिशा से एक मनमानी फसल का समर्थन करता था, और मैं चाहता था कि मुझे गतिशील रूप से फसल को बदलने की अनुमति दी जाए। मुझे पिकासो की अनुकूलता की भी आवश्यकता थी , और पिकासो ने छवि को आकर्षक रूप से सेट किया।

मेरे कार्यान्वयन को सीधे AOSP में ImageView.java से अनुकूलित किया गया है। इसका उपयोग करने के लिए, XML में ऐसा घोषित करें:

    <com.yourapp.PercentageCropImageView
        android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="matrix"/>

स्रोत से, यदि आप एक शीर्ष फसल चाहते हैं, तो कॉल करें:

imageView.setCropYCenterOffsetPct(0f);

यदि आप एक निचली फसल चाहते हैं, तो कॉल करें:

imageView.setCropYCenterOffsetPct(1.0f);

यदि आप नीचे रास्ते में 1/3 फसल चाहते हैं, तो कॉल करें:

imageView.setCropYCenterOffsetPct(0.33f);

इसके अलावा, यदि आप एक अन्य फसल विधि का उपयोग करने का चुनाव करते हैं, जैसे कि fit_center, आप ऐसा कर सकते हैं और इस कस्टम तर्क में से कोई भी ट्रिगर नहीं होगा। (अन्य कार्यान्वयन केवल आप उनके फसल विधियों का उपयोग करते हैं)।

अंत में, मैंने एक विधि जोड़ी, redraw (), इसलिए यदि आप कोड में गतिशील रूप से अपनी फसल पद्धति / स्केल बदलने का चुनाव करते हैं, तो आप व्यू को redraw करने के लिए बाध्य कर सकते हैं। उदाहरण के लिए:

fullsizeImageView.setScaleType(ScaleType.FIT_CENTER);
fullsizeImageView.redraw();

अपने कस्टम टॉप-सेंटर-थर्ड क्रॉप पर वापस जाने के लिए, कॉल करें:

fullsizeImageView.setScaleType(ScaleType.MATRIX);
fullsizeImageView.redraw();

यहाँ वर्ग है:

/* 
 * Adapted from ImageView code at: 
 * http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4.4_r1/android/widget/ImageView.java
 */
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

public class PercentageCropImageView extends ImageView{

    private Float mCropYCenterOffsetPct;
    private Float mCropXCenterOffsetPct;

    public PercentageCropImageView(Context context) {
        super(context);
    }

    public PercentageCropImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public PercentageCropImageView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
    }

    public float getCropYCenterOffsetPct() {
        return mCropYCenterOffsetPct;
    }

    public void setCropYCenterOffsetPct(float cropYCenterOffsetPct) {
        if (cropYCenterOffsetPct > 1.0) {
            throw new IllegalArgumentException("Value too large: Must be <= 1.0");
        }
        this.mCropYCenterOffsetPct = cropYCenterOffsetPct;
    }

    public float getCropXCenterOffsetPct() {
        return mCropXCenterOffsetPct;
    }

    public void setCropXCenterOffsetPct(float cropXCenterOffsetPct) {
        if (cropXCenterOffsetPct > 1.0) {
            throw new IllegalArgumentException("Value too large: Must be <= 1.0");
        }
        this.mCropXCenterOffsetPct = cropXCenterOffsetPct;
    }

    private void myConfigureBounds() {
        if (this.getScaleType() == ScaleType.MATRIX) {
            /*
             * Taken from Android's ImageView.java implementation:
             * 
             * Excerpt from their source:
    } else if (ScaleType.CENTER_CROP == mScaleType) {
       mDrawMatrix = mMatrix;

       float scale;
       float dx = 0, dy = 0;

       if (dwidth * vheight > vwidth * dheight) {
           scale = (float) vheight / (float) dheight; 
           dx = (vwidth - dwidth * scale) * 0.5f;
       } else {
           scale = (float) vwidth / (float) dwidth;
           dy = (vheight - dheight * scale) * 0.5f;
       }

       mDrawMatrix.setScale(scale, scale);
       mDrawMatrix.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
    }
             */

            Drawable d = this.getDrawable();
            if (d != null) {
                int dwidth = d.getIntrinsicWidth();
                int dheight = d.getIntrinsicHeight();

                Matrix m = new Matrix();

                int vwidth = getWidth() - this.getPaddingLeft() - this.getPaddingRight();
                int vheight = getHeight() - this.getPaddingTop() - this.getPaddingBottom();

                float scale;
                float dx = 0, dy = 0;

                if (dwidth * vheight > vwidth * dheight) {
                    float cropXCenterOffsetPct = mCropXCenterOffsetPct != null ? 
                            mCropXCenterOffsetPct.floatValue() : 0.5f;
                    scale = (float) vheight / (float) dheight;
                    dx = (vwidth - dwidth * scale) * cropXCenterOffsetPct;
                } else {
                    float cropYCenterOffsetPct = mCropYCenterOffsetPct != null ? 
                            mCropYCenterOffsetPct.floatValue() : 0f;

                    scale = (float) vwidth / (float) dwidth;
                    dy = (vheight - dheight * scale) * cropYCenterOffsetPct;
                }

                m.setScale(scale, scale);
                m.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));

                this.setImageMatrix(m);
            }
        }
    }

    // These 3 methods call configureBounds in ImageView.java class, which
    // adjusts the matrix in a call to center_crop (android's built-in 
    // scaling and centering crop method). We also want to trigger
    // in the same place, but using our own matrix, which is then set
    // directly at line 588 of ImageView.java and then copied over
    // as the draw matrix at line 942 of ImageVeiw.java
    @Override
    protected boolean setFrame(int l, int t, int r, int b) {
        boolean changed = super.setFrame(l, t, r, b);
        this.myConfigureBounds();
        return changed;
    }
    @Override
    public void setImageDrawable(Drawable d) {          
        super.setImageDrawable(d);
        this.myConfigureBounds();
    }
    @Override
    public void setImageResource(int resId) {           
        super.setImageResource(resId);
        this.myConfigureBounds();
    }

    public void redraw() {
        Drawable d = this.getDrawable();

        if (d != null) {
            // Force toggle to recalculate our bounds
            this.setImageDrawable(null);
            this.setImageDrawable(d);
        }
    }
}

5

हो सकता है कि एंड्रॉइड पर छवि को देखने के लिए स्रोत कोड में जाएं और देखें कि यह केंद्र की फसल आदि को कैसे खींचता है .. और शायद उस कोड को अपने तरीकों से कॉपी करें। मैं वास्तव में ऐसा करने से बेहतर समाधान के लिए नहीं जानता। मेरे पास बिटमैप (बिटमैप परिवर्तन की खोज) को मैन्युअल रूप से आकार देने और क्रॉप करने का अनुभव है जो इसके वास्तविक आकार को कम करता है, लेकिन यह अभी भी प्रक्रिया में एक ओवरहेड का एक सा बनाता है।


3
public class ImageViewTopCrop extends ImageView {
public ImageViewTopCrop(Context context) {
    super(context);
    setScaleType(ScaleType.MATRIX);
}

public ImageViewTopCrop(Context context, AttributeSet attrs) {
    super(context, attrs);
    setScaleType(ScaleType.MATRIX);
}

public ImageViewTopCrop(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    setScaleType(ScaleType.MATRIX);
}

@Override
protected boolean setFrame(int l, int t, int r, int b) {
    computMatrix();
    return super.setFrame(l, t, r, b);
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    computMatrix();
}

private void computMatrix() {
    Matrix matrix = getImageMatrix();
    float scaleFactor = getWidth() / (float) getDrawable().getIntrinsicWidth();
    matrix.setScale(scaleFactor, scaleFactor, 0, 0);
    setImageMatrix(matrix);
}

}


setFrame && onLayout
tianxia

computMatrix: आप यहाँ कोई भी मैट्रिक्स कर सकते हैं।
tianxia

onLayoutमुझे बहुत बचाता है! धन्यवाद! मुझे एक समस्या का सामना करना पड़ा है जहां यह मैट्रिक्स की गणना करता है लेकिन छवि को तुरंत प्रदर्शित नहीं करता है और onLayoutकोड को जोड़ने से मेरी समस्या हल हो जाती है।
natsumiyu

1

यदि आप फ्रेस्को (SimpleDraweeView) का उपयोग कर रहे हैं, तो आप इसे आसानी से कर सकते हैं:

 PointF focusPoint = new PointF(0.5f, 0f);
 imageDraweeView.getHierarchy().setActualImageFocusPoint(focusPoint);

यह एक शीर्ष फसल के लिए होगा।

संदर्भ लिंक पर अधिक जानकारी


0

यहाँ समाधान के साथ 2 समस्याएं हैं:

  • वे एंड्रॉइड स्टूडियो लेआउट संपादक में प्रस्तुत नहीं करते हैं (ताकि आप विभिन्न स्क्रीन आकारों और पहलू अनुपात पर पूर्वावलोकन कर सकें)
  • यह केवल चौड़ाई से तराजू है, इसलिए डिवाइस और छवि के पहलू अनुपात के आधार पर, आप नीचे की तरफ खाली जगह के साथ समाप्त कर सकते हैं

यह छोटा संशोधन समस्या को ठीक करता है (onDraw में स्थान कोड, और चौड़ाई और ऊंचाई के कारकों की जाँच करें):

@Override
protected void onDraw(Canvas canvas) {

    Matrix matrix = getImageMatrix();

    float scaleFactorWidth = getWidth() / (float) getDrawable().getIntrinsicWidth();
    float scaleFactorHeight = getHeight() / (float) getDrawable().getIntrinsicHeight();

    float scaleFactor = (scaleFactorWidth > scaleFactorHeight) ? scaleFactorWidth : scaleFactorHeight;

    matrix.setScale(scaleFactor, scaleFactor, 0, 0);
    setImageMatrix(matrix);

    super.onDraw(canvas);
}

-1

सरलतम समाधान: छवि को क्लिप करें

 @Override
    public void draw(Canvas canvas) {
        if(getWidth() > 0){
            int clipHeight = 250;
            canvas.clipRect(0,clipHeight,getWidth(),getHeight());
         }
        super.draw(canvas);
    }

यह छवि को स्केल नहीं करेगा यदि यह दृश्य से छोटा है, यही वजह है कि अन्य समाधान उतने सरल नहीं हैं।
ओल्डस्कूल 4664 22
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.