需求: 用 ImageView 显示一寸照为圆形头像
问题: 默认显示的是中间部分的正方形区域, 头发被遮挡;
解决: 用户上传的头像无非三种情况: 正方形, 纵向长图, 横向长图;
- 正方形: 直接显示;
- 纵向长图: 显示最上面的正方形区域;
- 横向长图: 显示中间区域的正方形区域;
下面给出思路图:
使用
布局:
<ImageView
android:id="@+id/ivAvatar"
android:layout_width="80dp"
android:layout_height="80dp" />
java代码:
ImageView ivAvatar= (ImageView) findViewById(R.id.ivAvatar);
//头像
Glide.with(mContext)
.load(iconUrl)
.dontAnimate()
.placeholder(R.mipmap.my_xinxi)
.error(R.mipmap.my_xinxi)
.diskCacheStrategy(DiskCacheStrategy.RESULT)
.transform(new CircleAvatarTransform(mContext))
.into(ivAvatar);
CircleAvatarTransform.java源码
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
/**
* 从一寸照中截取出圆形头像, 不遮挡头发和脸蛋的那种
*
* 纵向长图: 取最上面的正方形
* 横向长图: 取中间正方形
* 正方形: 不处理
* <p>
* 作者: geaosu
*/
public class CircleAvatarTransform extends BitmapTransformation {
public CircleAvatarTransform(Context context) {
super(context);
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return circleCrop(pool, toTransform);
}
private Bitmap circleCrop(BitmapPool pool, Bitmap source) {
int w = source.getWidth();
int h = source.getHeight();
Bitmap bitmapTemp = null;
if (w < h) {
//纵向长图: 要处理
int widthTemp = w >= h ? h : w;
int heightTemp = widthTemp;
int x = 0;
int y = 30;
if (y + heightTemp > h) {
y = 0;
}
//截取bitmap
bitmapTemp = Bitmap.createBitmap(source, x, y, widthTemp, heightTemp, null, false);
} else {
//横向长图, 正方形: 不处理
bitmapTemp = source;
}
int size = Math.min(bitmapTemp.getWidth(), bitmapTemp.getHeight());
int width = (bitmapTemp.getWidth() - size) / 2;
int height = (bitmapTemp.getHeight() - size) / 2;
Bitmap bitmap = pool.get(size, size, Bitmap.Config.ARGB_8888);
if (bitmap == null) {
bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader = new BitmapShader(bitmapTemp, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
if (width != 0 || height != 0) {
// source isn't square, move viewport to center
Matrix matrix = new Matrix();
matrix.setTranslate(-width, -height);
shader.setLocalMatrix(matrix);
}
paint.setShader(shader);
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
return bitmap;
}
@Override
public String getId() {
return getClass().getName();
}
}