web-dev-qa-db-ja.com

Picassoを使用して画像をフル幅および可変高にサイズ変更します

可変サイズ(幅と高さ)のImageViewを含むアダプターを持つlistViewがあります。 Picassoで読み込んだ写真のサイズを、レイアウトの最大幅と、写真の縦横比で指定される可変の高さに変更する必要があります。

私はこの質問をチェックしました: ピカソで画像を全幅に固定し、高さを固定

fit()は機能しますが、画像のアスペクト比を維持するものが見つかりません。

アダプタのレイアウトで高さを修正した場合、このコードは部分的に機能します。

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

しかし、listViewの写真の間に空白スペースが生成されるのは、写真がその高さを持たない可能性があるためです。

前もって感謝します。

76
wendigo

最後に、ピカソの変換を行ってそれを解決しました、ここにスニペットがあります:

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

さらに、これには、非表示およびエラー描画可能な組み込みピカソをロードするためのコールバックが含まれています。

エラーをデバッグするためにさらに情報が必要な場合は、onErrorCallback情報が「null」であるため、カスタムリスナー(Picassoビルダー)を実装する必要があります。 UIの動作にエラーがあることを知っているだけです。

これが誰かが多くの時間を節約するのに役立つことを願っています。

59
wendigo

Picasso 2.4.0以降、 この操作は現在直接サポートされています 。ディメンションの1つを0として.resize()リクエストを追加するだけです。たとえば、可変幅を使用するには、呼び出しは次のようになります。

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);
            }
        });
83
George Hilliard

私は同じ問題に出くわし、解決策を見つけるのに少し時間がかかりましたが、最終的に自分に合った何かに出くわしました。

まず、ピカソの呼び出しを

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

fitcenterInsideを削除します。次に、XMLのImageViewに次の行を追加する必要があります

Android:scaleType="fitStart"
Android:adjustViewBounds="true"

うまくいけばそれもあなたのために働くでしょう。

76
drspaceboo

5月承認済み回答は、複数のViewHolderに対して複数のViewsをバインドする場合を除き、すべてに役立ちます次に、Transformationのクラスを作成し、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);

それがあなたを助けることを願っています。

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

これにより、すべてのデバイスの画像の高さが可変になります

2
Kiran

レイアウト完了リスナーを追加し、レイアウトプロセスが完了したら(imageView)を呼び出すことに注意するシンプルなヘルパーを作成しました。

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

}

したがって、たとえばフラグメントのonViewCreated()でこのように簡単に使用できます。

new PicassoDelegate(customerPhoto, Picasso.with(getActivity()).load(user.getPhotoUrl()).centerCrop());
0
Dmytro
imageView.post(new Runnable() {
      @Override public void run() {
        Picasso.with(context)
            .resize(0, imageView.getHeight())
            .onlyScaleDown()
            .into(imageView, new ImageCallback(callback, null));
      }
    });
0
Igor Bykov

実際に、ズーム可能な機能を備えたCustomImageViewで画像をロード中に取得していました

エラーは

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

私は受け入れられた答えから与えられたコードを編集することでそれを解決しました。私の画像ビューの幅がすでにmatch_parentであるかのようにディスプレイの最大幅を取得しました。

if(!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
Vivek Barai
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

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

このコードを試してください、私のために働いた。

0
Afinas EM

imageViewを拡張し、次のように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
Jinichi