将图片转换成圆形图片,网上已有好多的案例,在这里总结几个Bitmap转换成圆形的几个方法以及遇到的问题
首先第一个方法:
public Bitmap toRoundBitmap(Bitmap bitmap) {
final int STROKE_WIDTH = 4;
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float roundPx;
float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
if (width <= height) {
roundPx = width / 2;
top = 0;
left = 0;
bottom = width;
right = width;
height = width;
dst_left = 0;
dst_top = 0;
dst_right = width;
dst_bottom = width;
} else {
roundPx = height / 2;
float clip = (width - height) / 2;
left = clip;
right = width - clip;
top = 0;
bottom = height;
width = height;
dst_left = 0;
dst_top = 0;
dst_right = height;
dst_bottom = height;
}
Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect src = new Rect((int) left, (int) top, (int) right,
(int) bottom);
final Rect dst = new Rect((int) dst_left, (int) dst_top,
(int) dst_right, (int) dst_bottom);
final RectF rectF = new RectF(dst);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(4);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, src, dst, paint);
// 画白色圆圈
paint.reset();
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(STROKE_WIDTH);
paint.setAntiAlias(true);
canvas.drawCircle(width / 2, width / 2, width / 2 - STROKE_WIDTH / 2,
paint);
return output;
}
之前用这个方法转正方形的图片没有问题,但是长方形的图片就会出现显示不全的问题,如图所示:
转换后
下面的两个方法可以解决这个问题:
public Bitmap toRoundBitmap(Bitmap bitmap) {
// 这里可能需要调整一下图片的大小来让你的图片能在圆里面充分显示
bitmap = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
// 构建一个位图对象,画布绘制出来的图片将会绘制到此bitmap对象上
Bitmap bm = Bitmap.createBitmap(200, 200, Config.ARGB_8888);
// 构建一个画布,
Canvas canvas = new Canvas(bm);
// 获得一个画笔对象,并设置为抗锯齿
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// 获得一种渲染方式对象
// BitmapShader的作用是使用一张位图作为纹理来对某一区域进行填充。
// 可以想象成在一块区域内铺瓷砖,只是这里的瓷砖是一张张位图而已。
Shader shader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);
// 设置画笔的渲染方式
paint.setShader(shader);
// 通过画布的画圆方法将渲染后的图片绘制出来
canvas.drawCircle(100, 100, 100, paint);
// 返回的就是一个圆形的bitmap对象
return bm;
}
或者是:
public Bitmap toRoundBitmap(Bitmap bitmap) {
// 前面同上,绘制图像分别需要bitmap,canvas,paint对象
bitmap = Bitmap.createScaledBitmap(bitmap, 400, 400, true);
Bitmap bm = Bitmap.createBitmap(400, 400, Config.ARGB_8888);
Canvas canvas = new Canvas(bm);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// 这里需要先画出一个圆
canvas.drawCircle(200, 200, 200, paint);
// 圆画好之后将画笔重置一下
paint.reset();
// 设置图像合成模式,该模式为只在源图像和目标图像相交的地方绘制源图像
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, 0, 0, paint);
return bm;
}
调用这两个方法就不会出现上面的那种状况了,下面看效果:
转换后
这样就不会出现显示不全的问题了。