我有一个垂直的LinearLayout,其中一个项目是使用Picasso加载的ImageView
。我需要将图像的宽度提升到整个设备宽度,并显示图像的中心部分被固定高度(150dp)裁剪。我目前有以下代码:
Picasso.with(getActivity())
.load(imageUrl)
.placeholder(R.drawable.placeholder)
.error(R.drawable.error)
.resize(screenWidth, imageHeight)
.centerInside()
.into(imageView);
我应该将哪些值放入screenWidth
和imageHeight
(= 150dp)?
答案 0 :(得分:462)
您正在寻找:
.fit().centerCrop()
这意味着什么:
fit
- 等到ImageView
被测量并调整图像大小以与其大小完全匹配。centerCrop
- 缩放符合宽高比的图像,直到它填充大小。裁剪顶部和底部或左右两侧,使其与尺寸完全匹配。答案 1 :(得分:8)
This blog详细解释了毕加索的调整大小和拟合函数:https://futurestud.io/tutorials/picasso-image-resizing-scaling-and-fit。
使用调整大小调整图像大小(x,y)
通常情况下,如果您的服务器或API以您需要的精确尺寸提供图像,这是最佳选择,这是带宽,内存消耗和图像质量之间的完美折衷。
不幸的是,要求完美尺寸的图像并不总是在您的掌控之中。如果图像的大小很奇怪,您可以使用resize(horizontalSize,verticalSize)调用将图像的尺寸更改为更合适的尺寸。这将在ImageView中显示之前调整图像大小。
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.resize(600, 200) // resizes the image to these dimensions (in pixel). does not respect aspect ratio
.into(imageViewResize);
使用scaleDown()
使用resize()选项时,Picasso也会升级您的图像。由于在不改善图像质量的情况下制作较小的图像可能会浪费计算时间,因此当原始图像的尺寸大于目标尺寸时,调用scaleDown(true)仅应用resize()。
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.resize(6000, 2000)
.onlyScaleDown() // the image will only be resized if it's bigger than 6000x2000 pixels.
.into(imageViewResizeScaleDown);
使用缩放避免拉伸图像
现在,与任何图像处理一样,调整图像大小可能会使宽高比失真并使图像显示变得丑陋。在大多数用例中,您希望防止这种情况发生。 Picasso在这里给你两个缓解选择,可以是call centerCrop()或centerInside()。
<强> CenterCrop 强>
CenterCrop()是一种裁剪技术,可以缩放图像,使其填充ImageView的请求边界,然后裁剪额外的图像。 ImageView将完全填充,但可能无法显示整个图像。
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.resize(600, 200) // resizes the image to these dimensions (in pixel)
.centerCrop()
.into(imageViewResizeCenterCrop);
<强> CenterInside 强>
CenterInside()是一种裁剪技术,可以缩放图像,使两个维度都等于或小于ImageView的请求范围。图像将完全显示,但可能无法填满整个ImageView。
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.resize(600, 200)
.centerInside()
.into(imageViewResizeCenterInside);
最后,但并非最不重要:毕加索适合() 讨论的选项应涵盖您对图像大小调整和缩放功能的需求。 Picasso有一个最后的辅助功能,它非常有用:fit()。
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.fit()
// call .centerInside() or .centerCrop() to avoid a stretched image
.into(imageViewFit);
fit()测量目标ImageView的尺寸,并在内部使用resize()将图像大小缩小为ImageView的尺寸。 fit()有两点需要了解。首先,调用fit()可以延迟图像请求,因为Picasso需要等到可以测量ImageView的大小。其次,你只能使用fit()和ImageView作为目标(我们稍后会看到其他目标)。
优点是图像处于尽可能低的分辨率,而不会影响其质量。较低的分辨率意味着要在缓存中保留较少的数据。这可以显着降低图像在应用内存占用中的影响。总之,如果您希望在更快的加载时间内降低内存影响,fit()是一个很好的工具。
答案 2 :(得分:0)
在某些情况下,fit()是无用的。在必须等待宽度和高度测量结束之前。因此,您可以使用globallayoutlistener。例如;
imageView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
Picasso.with(getActivity())
.load(imageUrl)
.placeholder(R.drawable.placeholder)
.error(R.drawable.error)
.resize(screenWidth, imageHeight)
.fit
.centerInside()
.into(imageView);
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});