昨天中秋加班,有个需求中用到一个 ImageView.ScaleType.CENTER_CROP 效果,见下:
本来以为一行代码的事儿,没想到 setScaleType 不生效,看代码是因为 bitmap 绘制了圆角导致冲突的。也是第一次遇到这个情况,知道了问题,当然就是一通 google,不过网上基本都是 Glide 库与 CENTER_CROP 的方案,在我这里并不适用。所以最后只能按照自己的思路搞了搞,在此记录下,如果你还有更好的方法,欢迎指正:
-
将原始 bitmap 直接按照 CENTER_CROP 进行裁剪
-
将裁剪后的 bitmap 做圆角处理
-
ImageView 直接使用最终的 bitmap
代码
我将裁剪方法贴下:
public static Bitmap cropBitmap(Bitmap src, int tagW, int tagH) {
final int srcW = src.getWidth();
final int srcH = src.getHeight();
final float xScale = (float) tagW / srcW;
final float yScale = (float) tagH / srcH;
final float scale = Math.max(xScale, yScale);
final float scaleW = scale * srcW;
final float scaleH = scale * srcH;
final float left = (tagW - scaleW) / 2;
final float top = (tagH - scaleH) / 2;
final RectF tagRect = new RectF(left, top, left + scaleW, top + scaleH); // 新bitmap裁剪区域
final Bitmap dst = Bitmap.createBitmap(tagW, tagH, src.getConfig());
final Canvas canvas = new Canvas(dst);
canvas.drawBitmap(src, null, tagRect, null);
return dst;
}
圆角处理方法也提供下:
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float[] rids) {
try {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth()
, bitmap.getHeight(), Bitmap.Config.ARGB_4444);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()));
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.BLACK);
Path path = new Path();
path.addRoundRect(rectF, rids, Path.Direction.CW); // rids[] 四个角的弧度值
canvas.drawPath(path, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
final Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
canvas.drawBitmap(bitmap, src, rect, paint);
return output;
} catch (OutOfMemoryError outOfMemoryError){
outOfMemoryError.printStackTrace();
return bitmap;
} catch (Exception e) {
TLog.e(TAG, TLog.USR, e);
return bitmap;
}
}
这是使用代码:
private void setRoundBitmap(Bitmap bitmap) {
Bitmap scaleBitmap = null;
try {
// 先裁剪成目标大小
scaleBitmap = NaviUtil.crop(bitmap, tagImgW, tagImgH);
float radius = NaviUtil.dp2px(getContext(), 8);
// float[] 2 个为一组,控制每个弧角
tagBitmap = NaviUtil.getRoundedCornerBitmap(scaleBitmap,
new float[] {0.0f, 0.0f, 0.0f, 0.0f
, radius, radius, radius, radius});
} catch (OutOfMemoryError outOfMemoryError) {
return;
} catch (Exception e) {
e.printStackTrace();
} finally {
recycleBitmap(bitmap);
recycleBitmap(scaleBitmap);
}
if (null != mImgView) {
mImgView.setImageBitmap(tagBitmap);
}
}
代码就这样了,希望对大家有帮助