চিত্রটি পূর্ণ প্রস্থে এবং পিকাসোর সাথে পরিবর্তনশীল উচ্চতায় পুনরায় আকার দিন


84

আমার সাথে একটি অ্যাডাপ্টার সহ একটি তালিকাভিউ রয়েছে ImageView যা ভেরিয়েবল আকার (প্রস্থ এবং উচ্চতা) । আমার পিকাসোর সাথে চিত্রের লোডটির আকারের আকারের অনুপাত দ্বারা সর্বাধিক প্রস্থের লেআউটের এবং একটি পরিবর্তনশীল উচ্চতা দিয়ে আকার পরিবর্তন করতে হবে।

আমি এই প্রশ্নটি যাচাই করেছি: পিকাসোর সাথে চিত্রটিকে পূর্ণ প্রস্থ এবং স্থির উচ্চতায় পুনরায় আকার দিন

দ্য fit()কাজ কিন্তু আমি ছবি অনুপাত রাখতে কিছুই পাই নি।

এই কোডটি আংশিকভাবে কাজ করে যদি আমি অ্যাডাপ্টারের বিন্যাসে উচ্চতা নির্ধারণ করি:

Picasso.with(this.context).load(message_pic_url)
.placeholder(R.drawable.profile_wall_picture)
.fit().centerInside()
.into(holder.message_picture);

তবে এটি তালিকাভিত্তিক চিত্রগুলির মধ্যে ফাঁকা স্থান তৈরি করে কারণ ছবিগুলি এর উচ্চতা নাও থাকতে পারে।

আগাম ধন্যবাদ.

উত্তর:


89

পিকাসো ২.৪.০ হিসাবে, এই অপারেশনটি এখন সরাসরি সমর্থিত । কেবল .resize()মাত্রা হিসাবে একটি অনুরোধ যোগ করুন 0। উদাহরণস্বরূপ, পরিবর্তনশীল প্রস্থের জন্য, আপনার কলটি হয়ে উঠবে:

Picasso.with(this.context)
       .load(message_pic_url)
       .placeholder(R.drawable.profile_wall_picture)
       .resize(0, holder.message_picture.getHeight()),
       .into(holder.message_picture);

নোট করুন যে এই কলটি ব্যবহার করে .getHeight()এবং সুতরাং ধরে নেওয়া হয়েছে message_pictureযে ইতিমধ্যে পরিমাপ করা হয়েছে। যদি এটি না হয়, যেমন আপনি যখন একটিতে একটি নতুন ভিউকে স্ফীত করেছেন, তখন আপনি ভিউটিতে একটি ListAdapterযোগ করে পরিমাপের পরে এই কলটি বিলম্ব করতে পারেন OnGlobalLayoutListener:

holder.message_picture.getViewTreeObserver()
      .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            // Wait until layout to call Picasso
            @Override
            public void onGlobalLayout() {
                // Ensure we call this only once
                imageView.getViewTreeObserver()
                         .removeOnGlobalLayoutListener(this);


                Picasso.with(this.context)
                       .load(message_pic_url)
                       .placeholder(R.drawable.profile_wall_picture)
                       .resize(0, holder.message_picture.getHeight())
                       .into(holder.message_picture);
            }
        });

8
এই সমাধানের সাথে আমি java.lang.IllegalArgumentException: At least one dimension has to be positive number.ঘূর্ণনের ক্ষেত্রে ত্রুটিটি পেয়েছি , এটি খণ্ডে রয়েছে, কেন এমন হতে পারে এমন কোনও ধারণা?
লুকাশজ 'সেভেরিয়ান' গ্রিলা

4
হুম, আমি যদি এই চেকটি যুক্ত করি তবে আমার আর এই সমস্যা নেই তবে চিত্রটির আকার পরিবর্তন করা যায় না ...
ম্রোবোআত

4
@ লুকাস'স্ভারিয়ান'গ্রেলা আমারও একই সমস্যা ছিল। মূল প্রশ্নের সাথে মেলে এই উদাহরণটি ঠিক করতে আপনাকে যুক্তিগুলি ঘুরিয়ে দিতে হবে:.resize(holder.message_picture.getWidth(), 0)
খ্রিস্টিয়ান

4
আপনি আমাকে ধারণা দিয়েছেন। ধন্যবাদ পরিবর্তনশীল উচ্চতা সহ পূর্ণ প্রস্থের চিত্র পেতে চাইলে তাদের ব্যবহার করুন: Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); int width = size.x; .resize(width, 0)
ফাহরুলাজমি

4
আমি এই পদ্ধতিটি ব্যবহার করেছি, আপনি যখন অ্যাপটিকে পটভূমিতে নিয়ে যান এবং ফিরে আসেন তখন কল onGlobalLayout()হয় না এবং চিত্র প্রদর্শিত হবে না।
গোখন আরিক

82

আমি একই ইস্যুটি জুড়ে এসেছি এবং সমাধানটি সন্ধান করতে আমার কিছুটা সময় নিয়েছে তবে অবশেষে আমি আমার পক্ষে কাজ করে এমন কিছু বিষয় পেলাম।

প্রথমত আমি পিকাসোর কলটিতে পরিবর্তন করেছি

Picasso.with(this.context).load(message_pic_url)
.placeholder(R.drawable.profile_wall_picture)
.into(holder.message_picture);

fitএবং অপসারণ করা হচ্ছে centerInside। এরপরে আপনাকে আপনার এক্সএমএলে ইমেজভিউতে নিম্নলিখিত লাইনগুলি যুক্ত করতে হবে

android:scaleType="fitStart"
android:adjustViewBounds="true"

আশা করি এটি আপনার পক্ষেও কাজ করবে।


4
ধন্যবাদ তবে এটি আমার পক্ষে কাজ করে না। আমি ছবিগুলি দেখতে পাচ্ছি না, বিটম্যাপের আকার সম্পর্কে ক্লাসিক সতর্কতা পেয়েছি (ক্লাসিক বার্তা: 2048x2048 সর্বোচ্চ আকার)।
wendigo

4
শুনে দুঃখিত হলাম. এটাই হবে এই পদ্ধতির অপূর্ণতা। চিত্রটি মোটেও আকার পরিবর্তন করতে পিকাসো পাচ্ছে না, এটি পুরো আকারে লোড করুন। স্মৃতি সমস্যার কারণ হতে পারে।
ক্যাসি

আপনাকে অনেক ধন্যবাদ. এটি একটি আকর্ষণীয়, দ্রুত এবং সহজের মতো কাজ করে;)
ফু

@drspaceboo আপনার layout_widthএবং ইমেজভিউতে কী layout_height? আমি চেষ্টা করছি match_parentএবং wrap_contentযথাক্রমে কিন্তু এটি কার্যকর হয় না :(
ভিকি চিজওয়ানি

@ ভিকি চিজওয়ানি স্মৃতি থেকে আমার মনে হয় আমার ওজন ছিল 0dpএবং 100% নিশ্চিত নয় এবং আমার মনে হয় না আমাদের প্রয়োগটিতে আর এটি রয়েছে। match_parent1
ক্যাসি

60

অবশেষে আমি এটি পিকাসোর রূপান্তর করে সমাধান করেছি, এখানে স্নিপেটটি রয়েছে:

    Transformation transformation = new Transformation() {

        @Override
        public Bitmap transform(Bitmap source) {
            int targetWidth = holder.message_picture.getWidth();

            double aspectRatio = (double) source.getHeight() / (double) source.getWidth();
            int targetHeight = (int) (targetWidth * aspectRatio);
            Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
            if (result != source) {
                // Same bitmap is returned if sizes are the same
                source.recycle();
            }
            return result;
        }

        @Override
        public String key() {
            return "transformation" + " desiredWidth";
        }
    };

    mMessage_pic_url = message_pic_url;

    Picasso.with(this.context)
        .load(message_pic_url)
        .error(android.R.drawable.stat_notify_error)
        .transform(transformation)
        .into(holder.message_picture, new Callback() {
            @Override
            public void onSuccess() {
                holder.progressBar_picture.setVisibility(View.GONE);
            }

            @Override
            public void onError() {
                Log.e(LOGTAG, "error");
                holder.progressBar_picture.setVisibility(View.GONE);
            }
    });

এই লাইনটি আপনার পছন্দসই প্রস্থের সাথে কাস্টমাইজ করার জন্য:

int targetWidth = holder.message_picture.getWidth();

অতিরিক্তভাবে এই স্নিপড পিকাসোর অন্তর্নির্মিত আড়াল এবং ত্রুটি আঁকতে লোড করার জন্য কলব্যাক অন্তর্ভুক্ত।

আপনার যদি কোনও ত্রুটি ডিবাগ করার জন্য আরও তথ্যের প্রয়োজন হয় তবে আপনাকে একটি কাস্টম শ্রোতা (পিকাসো নির্মাতা) কার্যকর করতে হবে onError Callback তথ্যটি "নাল"আপনি কেবল জানেন যে ইউআই আচরণের জন্য একটি ত্রুটি রয়েছে।

আমি আশা করি এটি কাউকে অনেক ঘন্টা বাঁচাতে সহায়তা করে।


দেখে মনে হচ্ছে আপনি কেবল উত্সটি পুনর্ব্যবহার করছেন ফলাফলের মত একই। আপনি নির্বিশেষে এটিকে পুনর্ব্যবহার করতে এবং ফলাফলটি ফিরে পেতে চান না?
ওয়েঙ্গার

@ ওয়েঞ্জার, না, পিকাসো অভিযোগ করেন যদি আপনি এটি করেন।
জর্জ হিলিয়ার্ড

দুর্দান্ত !! সত্যিই দুর্দান্ত
এলওজকার

হ্যাঁ, এটি কাজ করেছে। তবে মাইকেসে আমাকে ইমেজভিউ প্রস্থটি ম্যাচ_পিতা বা একটি নির্দিষ্ট প্রস্থে সেট করতে হয়েছিল। "র‌্যাপ_কন্টেন্ট" রূপান্তরটিতে 0 (শূন্য) প্রদান করে এবং একটি ব্যতিক্রম উত্থাপন করে।
রাগ করুনআইজি

স্ক্রোল করার সময়, কখনও কখনও holder.message_picture.getWidth()0 দেয় এবং এটি একটি ত্রুটির কারণ হয় width and height must be > 0। কোনও ত্রুটি কীভাবে এই ত্রুটিটি ঠিক করবেন?
শাহউদ উল হাসান

10

মে গৃহীত উত্তর সকলের জন্য দরকারী কিন্তু আপনি একাধিক বাঁধাই হয় ViewHolderএকাধিক জন্য Viewsতারপর আপনার জন্য ক্লাস তৈরি করে আপনার কোড কমে যায় ট্রান্সফরমেসন এবং ক্ষণস্থায়ী ImageView থেকে ViewHolder

/**
 * Created by Pratik Butani
 */
public class ImageTransformation {

    public static Transformation getTransformation(final ImageView imageView) {
        return new Transformation() {

            @Override
            public Bitmap transform(Bitmap source) {
                int targetWidth = imageView.getWidth();

                double aspectRatio = (double) source.getHeight() / (double) source.getWidth();
                int targetHeight = (int) (targetWidth * aspectRatio);
                Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
                if (result != source) {
                    // Same bitmap is returned if sizes are the same
                    source.recycle();
                }
                return result;
            }

            @Override
            public String key() {
                return "transformation" + " desiredWidth";
            }
        };
    }
}

থেকে কল করা ViewHolder:

Picasso.with(context).load(baseUrlForImage)
                     .transform(ImageTransformation.getTransformation(holder.ImageView1))
                     .error(R.drawable.ic_place_holder_circle)
                     .placeholder(R.drawable.ic_place_holder_circle)
                     .into(holder.mMainPhotoImageView1);

আশা করি এটা তোমাকে সাহায্য করবে.


ধন্যবাদ, ইমেজভিউয়ের দুর্দান্ত সমাধান, একটি প্রশ্ন: আমরা কী ভিডিওভিউ আকারের জন্য প্যারামিটারে ইমেজভিউ পাসের মতো করতে পারি?
ব্রজেশ

@ প্রতীক আমার কাছে পুনর্ব্যবহারযোগ্য দৃশ্য রয়েছে এবং যখন দ্রুত স্ক্রোল হয়, তখন আমি ব্যতিক্রম পেয়েছিলাম: রূপান্তর রূপান্তরটি পছন্দসই ব্যর্থতার সাথে ক্র্যাশ হয়েছিল। কারণ: java.lang.IllegalArgumentEception: প্রস্থ এবং উচ্চতা অবশ্যই> 0
ব্রজেশ

স্ক্রোল করার সময়, কখনও কখনও imageView.getWidth()0 দেয় এবং এটি একটি ত্রুটির কারণ হয় width and height must be > 0। কোনও ত্রুটি কীভাবে এই ত্রুটিটি ঠিক করবেন?
শাহউদ উল হাসান

সেক্ষেত্রে আপনার ইমেজ ইউআরএল নাল হতে পারে তাই শূন্য আছে কিনা তা আগে পরীক্ষা করে দেখুন।
প্রতীক বুটানি

3
    Picasso.with(this).load(url).resize(1800, 1800).centerInside().into(secondImageView)

    <ImageView
        android:id="@+id/SecondImage"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:adjustViewBounds="true"
        android:layout_margin="10dp"
        android:visibility="gone"/>

এটি আপনাকে সমস্ত ডিভাইসের জন্য চিত্রের পরিবর্তনশীল উচ্চতা নিয়ে সহায়তা করবে


0

আমি সরল সহায়ক লিখেছি যা লেআউট সম্পূর্ণ শ্রোতা যুক্ত করার বিষয়ে যত্ন নেয় এবং লেআউট প্রক্রিয়াটি সম্পূর্ণ হওয়ার পরে (ইমেজভিউ) কল করে।

public class PicassoDelegate {

private RequestCreator mRequestCreator;

public PicassoDelegate(ImageView target, RequestCreator requestCreator) {
    if (target.getWidth() > 0 && target.getHeight() > 0) {
        complete(target, requestCreator);
    } else {
        mRequestCreator = requestCreator;
        target.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                v.removeOnLayoutChangeListener(this);
                complete((ImageView) v, mRequestCreator);
            }
        });

    }

}

private void complete(ImageView target, RequestCreator requestCreator) {
    if (target.getWidth() > 0 && target.getHeight() > 0) {
        requestCreator.resize(target.getWidth(), target.getHeight());
    }

    requestCreator.into(target);
}

}

সুতরাং আপনি সহজেই এটি সহজেই ব্যবহার করতে পারেন উদাহরণস্বরূপ খণ্ডের অনভিউতে তৈরি ()

new PicassoDelegate(customerPhoto, Picasso.with(getActivity()).load(user.getPhotoUrl()).centerCrop());

0
imageView.post(new Runnable() {
      @Override public void run() {
        Picasso.with(context)
            .resize(0, imageView.getHeight())
            .onlyScaleDown()
            .into(imageView, new ImageCallback(callback, null));
      }
    });

0
public class CropSquareTransformation implements Transformation {

  private int mWidth;
  private int mHeight;

  @Override public Bitmap transform(Bitmap source) {
    int size = Math.min(source.getWidth(), source.getHeight());

    mWidth = (source.getWidth() - size) / 2;
    mHeight = (source.getHeight() - size) / 2;

    Bitmap bitmap = Bitmap.createBitmap(source, mWidth, mHeight, size, size);
    if (bitmap != source) {
      source.recycle();
    }

    return bitmap;
  }

  @Override public String key() {
    return "CropSquareTransformation(width=" + mWidth + ", height=" + mHeight + ")";
  }

আরও রূপান্তর: https://github.com/wasabeef/picasso-transformations


এই ক্ষেত্রে layout_widthএবং layout_heightএর কী হওয়া উচিত ImageView?
শাহেদ উল হাসান

0

ইমেজভিউ প্রসারিত করুন তারপরে নীচের মতো onMeasure পদ্ধতিটি ওভাররাইড করুন।

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
        Drawable d = getDrawable();

        if(d!=null && fittingType == FittingTypeEnum.FIT_TO_WIDTH){
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth());
            setMeasuredDimension(width, height);
        }else{
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

0

প্রকৃতপক্ষে আমি কাস্টমআইমেজভিউতে চিত্রটি লোড করার সময় প্রবেশ করছিলাম যার মধ্যে চিড়িয়াখানা কার্যকর ছিল

ত্রুটি ছিল

java.lang.RuntimeException: Transformation transformation desiredWidth crashed with exception.

আমি এটি গ্রহণযোগ্য উত্তর থেকে প্রদত্ত কোড সম্পাদনা করে সমাধান করেছি আমি আমার ডিসপ্লেটির সর্বোচ্চ প্রস্থ পেয়েছি যেন আমার ইমেজভিউ প্রস্থ ইতিমধ্যে ম্যাচ_প্যারেন্ট ছিল।

যদি (! imgUrl.equals ("")) {

        DisplayMetrics displayMetrics = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int height = displayMetrics.heightPixels;
        int width = displayMetrics.widthPixels;

        Picasso.with(context).load(imgUrl)
                .transform(getTransformation(width, imageView))
                .into(imageView, new Callback() {
                    @Override
                    public void onSuccess() {
                        if (progressBar != null) {
                            progressBar.setVisibility(View.GONE);
                        }
                    }

                    @Override
                    public void onError() {
                        if (progressBar != null) {
                            progressBar.setVisibility(View.GONE);
                        }
                    }
                });
    }

    public static Transformation getTransformation(final int width, final ImageView imageView) {
        return new Transformation() {
            @Override
            public Bitmap transform(Bitmap source) {
                int targetWidth = width;
                double aspectRatio = (double) source.getHeight() / (double) source.getWidth();
                int targetHeight = (int) (targetWidth * aspectRatio);
                Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
                if (result != source) {
                    // Same bitmap is returned if sizes are the same
                    source.recycle();
                }
                return result;
            }

            @Override
            public String key() {
                return "transformation" + " desiredWidth";
            }
        };
    }

0
Picasso.get()
.load(message_pic_url)
.fit()
.centerCrop()
.placeholder(R.drawable.profile_wall_picture)
.into(holder.message_picture);

এই কোডটি ব্যবহার করে দেখুন, আমার জন্য কাজ করেছেন।


0
@Override
    protected void onResume() {
        super.onResume();

        imageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                loadImageIfReady();
            }
        });

    }

    private void loadImageIfReady() {
        if (imageView.getMeasuredWidth() <= 0 || mPayload == null)
            this.finish();    // if not ready GTFO

        Picasso.with(this)
                    .load(mPayload)
                    .resize(imageView.getMeasuredWidth(), imageView.getMeasuredWidth())
                    .centerInside()
                    .into(imageView);


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