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
Resize image to full width and variable height with Picasso
提问by wendigo
I have a listView with an adapter that contains ImageView
of 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 onError
Callback
information is "null". You only know that there is an error for UI behavior.
如果您需要更多信息来调试任何错误,您必须实现自定义侦听器(Picasso builder),因为该onError
Callback
信息为“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_picture
has 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 OnGlobalLayoutListener
to 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 fit
and the centerInside
. Next you need to add the following lines to the ImageView in your XML
删除fit
和centerInside
。接下来,您需要将以下行添加到 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 ViewHolder
for Multiple Views
then 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
回答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.
试试这个代码,为我工作。