你如何缩放像 centerCrop 这样的 ImageView,但是从顶部开始?
Posted
技术标签:
【中文标题】你如何缩放像 centerCrop 这样的 ImageView,但是从顶部开始?【英文标题】:How do you scale an ImageView like centerCrop, but from top? 【发布时间】:2016-07-07 02:37:53 【问题描述】:假设我从 API 获取一些图像。我不知道图像的尺寸会提前是多少,但我知道我希望该图像成为ImageView
的src
,我已设置为某个特定大小。我希望从 API 获得的任何图像都填充整个ImageView
,我想保持纵横比,并且我不在乎一个维度(宽度或高度)是否对于视图的设置大小来说太大了——所以我用centerCrop
。
<ImageView
android:layout_
android:layout_
android:scaleType="centerCrop" />
如果从 API 返回的图像是这样的:
当它被设置为ImageView
的src 时,结果将类似于此(阴影部分被剪掉):
但是,我收到一个要求,我们应该始终显示图像的顶部并从下向上裁剪。所以想要的结果是这样的:
我确信这是可能的,但我是一个在他的联盟之外经营的网络人。以某种方式扩展ImageView
,或者尝试scaleType="matrix"
和setImageMatrix()
,或者第三个未提及的选项会更好吗?
【问题讨论】:
可能重复***.com/questions/6330084/imageview-scaling-top-crop How set imageview scaletype to topCrop的可能重复 【参考方案1】:使用这个TopCropImageView gist
import android.content.Context;
import android.graphics.Matrix;
import android.widget.ImageView;
/**
* ImageView to display top-crop scale of an image view.
*
* @author Chris Arriola
*/
public class TopCropImageView extends ImageView
public TopCropImageView(Context context)
super(context);
setScaleType(ScaleType.MATRIX);
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
super.onLayout(changed, left, top, right, bottom);
recomputeImgMatrix();
@Override
protected boolean setFrame(int l, int t, int r, int b)
recomputeImgMatrix();
return super.setFrame(l, t, r, b);
private void recomputeImgMatrix()
final Matrix matrix = getImageMatrix();
float scale;
final int viewWidth = getWidth() - getPaddingLeft() - getPaddingRight();
final int viewHeight = getHeight() - getPaddingTop() - getPaddingBottom();
final int drawableWidth = getDrawable().getIntrinsicWidth();
final int drawableHeight = getDrawable().getIntrinsicHeight();
if (drawableWidth * viewHeight > drawableHeight * viewWidth)
scale = (float) viewHeight / (float) drawableHeight;
else
scale = (float) viewWidth / (float) drawableWidth;
matrix.setScale(scale, scale);
setImageMatrix(matrix);
【讨论】:
我还在你的 gist 中添加了这个类的 Kotlin 版本:gist.github.com/arriolac/3843346#gistcomment-3604153【参考方案2】:如果您使用 Glide,则可以使用自定义转换。随意使用我的(这是 Glide 的 CenterCrop 类的几乎完全相同的副本),它需要百分比:
https://gist.github.com/bjornson/3ff8888c09908d5c6cc345d0a8e1f6a7
像任何其他位图转换一样使用它:
Glide.with(getContext())
.load(imagePath)
.transform(new PositionedCropTransformation(getContext(), 1, 0))
.into(imageView);
常用值: 左上方: 0, 0 右上: 0, 1 左下方: 1, 0 右下角: 1, 1
使用 0.5f 作为中心
【讨论】:
这不适用于 Glide 4.x。我插入的所有值都向右裁剪【参考方案3】:PositionedCropTransformation 转换代码以支持 Glide v4.x https://gist.github.com/bjornson/3ff8888c09908d5c6cc345d0a8e1f6a7
【讨论】:
【参考方案4】:如果你使用 Glide,你可以通过这种方式使用 optionalTransform:
Glide.with(context).load("http:///...")
.override(300, 300)
.optionalTransform(
new Transformation<Bitmap>()
@NonNull
@Override
public Resource<Bitmap> transform(@NonNull Context context,
@NonNull Resource<Bitmap> resource, int outWidth, int outHeight)
resource.get().setHeight(YOUR_CUSTOM_HIGHT);
return resource;
@Override
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest)
)
into(binding.img);
【讨论】:
以上是关于你如何缩放像 centerCrop 这样的 ImageView,但是从顶部开始?的主要内容,如果未能解决你的问题,请参考以下文章