Android 使用毕加索将图像调整为全宽和可变高度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21889735/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:16:08  来源:igfitidea点击:

Resize image to full width and variable height with Picasso

androidpicasso

提问by wendigo

I have a listView with an adapter that contains ImageViewof variable size (width and height). I need resize the pictures load with Picasso to the max width of layout and a variable height given by the aspect ratio of the picture.

我有一个带有ImageView可变大小(宽度和高度)的适配器的 listView 。我需要将 Picasso 加载的图片调整为布局的最大宽度和由图片的纵横比给出的可变高度。

I have checked this question: Resize image to full width and fixed height with Picasso

我已经检查过这个问题: Resize image to full width and fixed height with Picasso

The fit()works but I haven't found nothing to keep the aspect ratio of the picture.

fit()工作,但我还没有发现什么,以保持画面的纵横比。

This code partially works if I fixed the height in the layout of the adapter:

如果我固定了适配器布局中的高度,则此代码部分起作用:

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

But it generates blank spaces between the pictures of the listView because the pictures may be that not have that height.

但它会在 listView 的图片之间产生空白,因为图片可能没有那个高度。

Thanks in advance.

提前致谢。

采纳答案by wendigo

Finally I solved it doing a transformation of Picasso, here is the snippet:

最后我通过毕加索的转换解决了它,这是片段:

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

This line is for customize with your desired width:

此行用于自定义您所需的宽度:

int targetWidth = holder.message_picture.getWidth();

Additionally this snipped include Callback for loading hide and error drawable built-in Picasso.

此外,此剪辑包括用于加载隐藏和错误可绘制内置毕加索的回调。

If you need more information to debug any error, you MUST implement a custom listener (Picasso builder) beacuse the onErrorCallbackinformation is "null". You only know that there is an error for UI behavior.

如果您需要更多信息来调试任何错误,您必须实现自定义侦听器(Picasso builder),因为该onErrorCallback信息为“null”。您只知道 UI 行为存在错误。

I hope this helps someone to save many hours.

我希望这可以帮助某人节省很多时间。

回答by George Hilliard

As of Picasso 2.4.0, this operation is now directly supported. Simply add a .resize()request with one of the dimensions as 0. For example, to have a variable width, your call would become:

从 Picasso 2.4.0 开始,现在直接支持此操作。只需添加一个.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);

Note that this call uses .getHeight()and therefore assumes the message_picturehas already been measured. If that isn't the case, such as when you have inflated a new view in a ListAdapter, you can delay this call until after measurement by adding an OnGlobalLayoutListenerto the view:

请注意,此调用使用.getHeight()并因此假定message_picture已经测量。如果不是这种情况,例如当您在 a 中扩充了一个新视图时ListAdapter,您可以通过向OnGlobalLayoutListener视图添加 a来将此调用延迟到测量之后:

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

回答by drspaceboo

I came across the same issue and it took me a while to track down a solution but I finally came across something that works for me.

我遇到了同样的问题,我花了一段时间才找到解决方案,但我终于找到了对我有用的东西。

Firstly I changed the Picasso call to

首先,我将毕加索的电话改为

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

Removing the fitand the centerInside. Next you need to add the following lines to the ImageView in your XML

删除fitcenterInside。接下来,您需要将以下行添加到 XML 中的 ImageView

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

Hopefully it will work for you as well.

希望它也适用于您。

回答by Pratik Butani

May AcceptedAnswer is Useful to all but If you are binding Multiple ViewHolderfor Multiple Viewsthen you can reduce your code by Creating Class for Transformationand passing ImageViewfrom ViewHolder.

五月接受的答案是有用的,但一切如果你是结合多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";
            }
        };
    }
}

Calling from ViewHolder:

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

Hope it will Help you.

希望它会帮助你。

回答by Kiran

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

This will help you with variable height of images for all devices

这将帮助您为所有设备设置可变高度的图像

回答by Igor Bykov

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

回答by Pablo Cegarra

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

More transformations: https://github.com/wasabeef/picasso-transformations

更多转换:https: //github.com/wasabeef/picasso-transformations

回答by Jinichi

extend ImageView then override onMeasure method like the following.

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

回答by Vivek Barai

Actually i was getting in while loading image in CustomImageView which had zoomable functionality

实际上我是在加载具有可缩放功能的 CustomImageView 中的图像时进入的

Error was

错误是

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

I solved it by editing code given from accepted answer i got the max width of my display as if my imageview width was already match_parent.

我通过编辑接受的答案给出的代码解决了这个问题,我得到了显示的最大宽度,就好像我的图像视图宽度已经是 match_parent 一样。

if (!imgUrl.equals("")) {

如果 (!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";
            }
        };
    }

回答by Afinas EM

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

Try this code, Worked for me.

试试这个代码,为我工作。