ইমেজভিউ স্কেলিং TOP_CROP


88

আমার একটি রয়েছে ImageViewযা একটি পিএনজি প্রদর্শন করছে যা ডিভাইসের চেয়ে বেশি অনুপাতযুক্ত (উল্লম্বভাবে বলতে - যার অর্থ এটি দীর্ঘ)। আমি অনুপাতের অনুপাত বজায় রেখে, পিতামাতার প্রস্থের সাথে মিলে যাওয়া এবং চিত্রদর্শনটি পর্দার শীর্ষে পিন করার সময় এটি প্রদর্শন করতে চাই।

CENTER_CROPস্কেল প্রকার হিসাবে ব্যবহার করতে আমার যে সমস্যাটি রয়েছে তা হ'ল এটি (বোঝা যাবে) উপরের প্রান্তটি উপরের প্রান্তটি চিত্রের দৃশ্যে প্রান্তিককরণের পরিবর্তে স্কেলড চিত্রটিকে কেন্দ্র করবে।

সমস্যাটি FIT_STARTহ'ল চিত্রটি স্ক্রিনের উচ্চতায় ফিট করবে এবং প্রস্থটি পূরণ করবে না।

আমি কাস্টম onDraw(Canvas)ইমেজভিউ ব্যবহার করে এবং ক্যানভাস ব্যবহার করে ম্যানুয়ালি এটিকে হ্যান্ডেল করে এই সমস্যাটি সমাধান করেছি ; এই পদ্ধতির সমস্যাটি হ'ল 1) সহজ সমাধান হতে পারে তা নিয়ে আমি উদ্বিগ্ন, 2) super(AttributeSet)গাদা 3 এমবি নিখরচায় যখন 330 কেবি এর এসসিআর ইমগ সেট করার চেষ্টা করতে কনস্ট্রাক্টরে ফোন করার সময় আমি একটি ভিএম মেম ব্যতিক্রম পাচ্ছি am (6 এমবি এর একটি গাদা আকারের সাথে) এবং কেন এটি করতে পারে তা প্রকাশ করতে পারে না।

কোন ধারণা / পরামর্শ / সমাধান অনেক স্বাগত :)

ধন্যবাদ

পিএস আমি ভেবেছিলাম যে সমাধানটি ম্যাট্রিক্স স্কেল টাইপের ব্যবহার এবং এটি নিজেই করাতে পারে তবে এটি আমার বর্তমান সমাধানের চেয়ে একই বা বেশি কাজ বলে মনে হচ্ছে!


4
আপনি কি CENTER_CROP দিয়ে চেষ্টা করেছেন এবং চিত্র দেখুনের সাথে অ্যাডজাস্ট ভিউবাউন্ডসের সম্পত্তিটিকে সত্য হিসাবে সেট করেছেন?
প্রভিনভিনজি

4
হ্যাঁ আমি চেষ্টা করেছি যে, কোনও সাফল্যই আমি ভয় পাচ্ছি না যতক্ষণ না এটি তার পিতামাতার প্রশস্ত হওয়া অবধি দৃষ্টিভঙ্গি প্রসারিত করবে যা স্ক্রিনের চেয়ে বড় হবে না এবং তারপরে অতিরিক্ত উচ্চতা / 2 দিয়ে শীর্ষে ছাঁটাই করে পর্দায় চিত্রটি কেন্দ্র করে রাখবে এবং নীচে
ডোরি

উত্তর:


84

ঠিক আছে, আমার একটি কার্যকরী সমাধান রয়েছে have ডারকো থেকে প্রদত্ত প্রম্পটটি আমাকে আবার চিত্রবিউ ক্লাসে নজর দিয়েছে (ধন্যবাদ) এবং ম্যাট্রিক্স ব্যবহার করে রূপান্তরটি প্রয়োগ করেছে (যেমন আমি সন্দেহ করি তবে আমার প্রথম প্রয়াসে সাফল্য ছিল না!)। আমার কাস্টম ইমেজভিউ ক্লাসে আমি কনস্ট্রাক্টরের 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()ইমেজভিউয়ের মতো পদ্ধতিটিতে অন্তর্ভুক্ত করেছি যেমন কলটি configureBounds()এই পদ্ধতির মধ্যে রয়েছে, যেখানে সমস্ত স্কেলিং এবং ম্যাট্রিক্স স্টাফ হয় সেখানে আমার পক্ষে যুক্তিযুক্ত মনে হয় (যদি আপনি একমত না হন তবে বলুন)

নীচে এওএসপি থেকে সুপার.সেটফ্রেম () পদ্ধতি রয়েছে

 @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;
    }

এখানে পূর্ণ শ্রেণীর এসসিআর সন্ধান করুন


কোডটির জন্য ধন্যবাদ, ডরিডোরি! এটা ঠিক আছে! আপনার ব্যাখ্যাতে আপনি কেন "সেটফ্রেম" পদ্ধতির পুনরাবৃত্তি করলেন তা আমি বুঝতে পারি না ... আমি সফলতার সাথে প্রথমটি ব্যবহার করেছি (এবং দ্বিতীয়
এক্সডিটিকে

4
দুই ঘন্টা ধরে এক্সএমএল লেআউটের মাধ্যমে এর সাথে লড়াই করার পরে, এটি কাজ করেছিল। আমি আশা করি আমি আপনাকে আরও upboats দিতে পারে।
বিটন

4
আমাকে শরীরের আগে সুপার () কল করতে হবে অন্যথায় চিত্রটি পুনরায় রঙ ছাড়াই প্রদর্শিত হবে না
শেরপ্যা

4
@ ভিটারহাগোশ্যাবাব আপনাকে ম্যাট্রিক্স.পোস্টট্রান্সলেট (..) এর মতো থেমস ব্যবহার করতে হবে
আন্তন কিজেমা

4
পটভূমি ব্যবহার করতে পারবেন না? কেবল এসসিআর ব্যবহার করবেন?
Egos Zhang

43

নীচে এটিকে কেন্দ্র করার জন্য আমার কোডটি এখানে। বিটিডব্লিউ ডোরির কোডে কিছুটা বাগ রয়েছে: যেহেতু 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

@ জয় এটি দুর্দান্ত কাজ করে। আমি অন-লেআউট () পদ্ধতিতে ম্যাট্রিক্স কম্পিউটেশন তৈরি করছি, যা ঘোরানোর সময়ও কল হয়ে যায়, যেখানে সেট ফ্রেম দেয় না।
বক্স

এই জন্য ধন্যবাদ, নিখুঁতভাবে কাজ করে, এবং দ্রুত নীচের ফসলটি শীর্ষ ফসলে পরিবর্তনের জন্য একটি কোডের 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কার্যকারিতা দেবে।


4
এটি আমার পক্ষে কাজ করেছে। যাইহোক, আমি scaleRation চেক করতে যদি তা না হয় আছে <1 আমি তখন মাত্র পরিবর্তন 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

ডোরির ভিত্তিতে আমি এমন একটি সমাধান ব্যবহার করছি যা আশেপাশের ধারককে সর্বদা পূরণ করার জন্য চিত্রের প্রস্থ বা উচ্চতার উপর ভিত্তি করে চিত্রটিকে স্কেল করে। এটি কোনও কেন্দ্রকে উত্স হিসাবে কেন্দ্রের পরিবর্তে চিত্রের উপরের বামদিকটি ব্যবহার করে পুরো উপলব্ধ স্থান পূরণ করতে একটি চিত্রকে স্কেলিংয়ের অনুমতি দেয় :

@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
এটিই আরও ভাল সমাধান ... এবং যুক্ত করুন: ভাসমান প্রস্থ = আর - এল; ভাসমান উচ্চতা = b - t;
জেলট্রুড

9

এই সমাধানগুলির কোনওটিই আমার পক্ষে কাজ করেনি, কারণ আমি এমন একটি শ্রেণি চেয়েছিলাম যা অনুভূমিক বা উল্লম্ব দিক থেকে একটি স্বেচ্ছাসেবী ফসলকে সমর্থন করে এবং আমি চেয়েছিলাম যে এটি আমার ক্রপটিকে পরিবর্তনশীলভাবে পরিবর্তন করতে দেয়। আমার পিকাসোর সামঞ্জস্যতাও দরকার ছিল এবং পিকাসো আলস্যভাবে চিত্র অঙ্কনযোগ্য সেট করে।

আমার বাস্তবায়নটি এওএসপিতে সরাসরি চিত্রভিউ.জভা থেকে অভিযোজিত । এটি ব্যবহার করতে, এক্সএমএলে এর মতো ঘোষণা করুন:

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

তদতিরিক্ত, যদি আপনি ফিট_সেন্টারের মতো অন্য শস্য পদ্ধতি ব্যবহার করার সিদ্ধান্ত নেন তবে আপনি এটি করতে পারেন এবং এই কাস্টম যুক্তির কোনওটিই ট্রিগার হবে না। (অন্যান্য বাস্তবায়ন কেবলমাত্র তাদের ক্রপিং পদ্ধতিগুলি আপনাকে ব্যবহার করতে দেয়)।

শেষ অবধি, আমি একটি পদ্ধতি যুক্ত করেছি, পুনরায় আঁকুন (), সুতরাং যদি আপনি কোডটিতে গতিশীলভাবে আপনার ক্রপ পদ্ধতি / স্কেলটাইপ পরিবর্তন করতে বেছে নেন, আপনি দৃশ্যের পুনরায় চিত্র আঁকতে বাধ্য করতে পারেন। উদাহরণ স্বরূপ:

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

}


কম্পিউটম্যাট্রিক্স: আপনি এখানে যে কোনও ম্যাট্রিক্স করতে পারেন।
tianxia

onLayoutআমাকে অনেক বাঁচায়! ধন্যবাদ! আমি এমন একটি সমস্যার মুখোমুখি হয়েছি যেখানে এটি ম্যাট্রিক্সের গণনা করে তবে তাত্ক্ষণিকভাবে চিত্রটি প্রদর্শন করে না এবং onLayoutকোডে যুক্ত করা আমার সমস্যা সমাধান করে।
নাটসুমিয়ু

1

আপনি যদি ফ্রেসকো (সিম্পলড্রাভিউ ভিউ) ব্যবহার করছেন তবে আপনি এটির মাধ্যমে এটি সহজেই করতে পারেন:

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

এই এক শীর্ষ শস্য জন্য হবে।

রেফারেন্স লিংকে আরও তথ্য


0

সমাধানগুলির সাথে এখানে 2 টি সমস্যা রয়েছে:

  • তারা অ্যান্ড্রয়েড স্টুডিও লেআউট সম্পাদকটিতে রেন্ডার করে না (যাতে আপনি বিভিন্ন স্ক্রিনের আকার এবং দিক অনুপাতের উপর প্রাকদর্শন করতে পারেন)
  • এটি কেবল প্রস্থ অনুসারে স্কেল করে, সুতরাং ডিভাইস এবং চিত্রের অনুপাতের উপর নির্ভর করে আপনি নীচে একটি খালি স্ট্রিপ দিয়ে শেষ করতে পারেন

এই ছোট্ট পরিবর্তনটি সমস্যাটি সমাধান করে (অনড্রগুলিতে কোড রাখুন, এবং প্রস্থ এবং উচ্চতা মাপের কারণগুলি পরীক্ষা করুন):

@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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.