上篇博客中,我全面介绍了Xfermode相关的知识点,如果还没看过的小伙伴,建议你先去看上篇博客——初始Xfermode,对PorterDuffXfermode的18种模式做了详细的介绍,而且我也自己实现了官网的18种效果。这篇文章主要是记录下,PorterDuffXfermode在开发中常见的应用,比如:实现圆角、圆形等等,只要你可以画出来的形状都可以做。
效果图:
DST_IN模式:
以上效果图就是用的这种模式,我们先看下这种模式的效果:
上次我们已经说过了:显示目标图与源图的交集,且只显示目标图部分(可能你看到这里一脸懵逼,所以呀,去看上篇文章,你就懂了)
那么我们的圆角图到底怎么实现的呢?
思路:根据我们的DST_IN模式,可以先画出一个圆角矩形作为源图,然后画笔对象设置为DST_IN模式,接着把我们的设置为头像的图片画上去,就可以了。
下面看下代码:
public class PorterDuffXfermodeView extends ImageView {
private static final Xfermode sXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
private Bitmap mMaskBitmap;
private Paint mPaint;
int type;//绘制形状
public static final int CIRCLE = 0;//原型
public static final int ROUNDRECT = 1;//圆角
public static final int HEART = 2;//心形
public static final int OVAL = 3;//椭圆
public PorterDuffXfermodeView(Context context) {
super(context);
init();
}
public PorterDuffXfermodeView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
TypedArray array = context.obtainStyledAttributes(attrs,
R.styleable.pdxView);
type = array.getInt(R.styleable.pdxView_type, 0);// 默认为Circle
array.recycle();
}
public PorterDuffXfermodeView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
@Override
protected void onDraw(Canvas canvas) {
Bitmap bitmap = null;
Drawable drawable = getDrawable();
if (drawable != null) {
bitmap = Bitmap.createBitmap(getWidth(),
getHeight(), Bitmap.Config.ARGB_8888);
Canvas bitmapCanvas = new Canvas(bitmap);
drawable.setBounds(0, 0, getWidth(), getHeight());
drawable.draw(bitmapCanvas);
if (mMaskBitmap == null || mMaskBitmap.isRecycled()) {
switch (type) {
case CIRCLE:
mMaskBitmap = getBitmapCircle(getWidth(), getHeight());
break;
case ROUNDRECT:
mMaskBitmap = getBitmapRoundRect(getWidth(), getHeight());
break;
case HEART:
mMaskBitmap = getBitmapHeart(getWidth(), getHeight());
break;
case OVAL:
mMaskBitmap = getBitmapOval(getWidth(), getHeight());
break;
}
}
mPaint.setXfermode(sXfermode);
bitmapCanvas.drawBitmap(mMaskBitmap, 0.0f, 0.0f, mPaint);
//这里混合模式,上面设置完后,要再次设置为null
mPaint.setXfermode(null);
canvas.drawBitmap(bitmap, 0.0f, 0.0f, mPaint);
}
}
//圆角矩形
public static Bitmap getBitmapRoundRect(int width, int height) {
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLACK);
canvas.drawRoundRect(new RectF(0.0f, 0.0f, width, height), 50, 50, paint);
return bitmap;
}
//圆形
public static Bitmap getBitmapCircle(int width, int height) {
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
canvas.drawCircle(width / 2, height / 2, Math.min(width / 2, height / 2), paint);
return bitmap;
}
//心形
public static Bitmap getBitmapHeart(int width, int height) {
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLACK);
Path path = new Path();
path.addArc(200, 200, 400, 400, -225, 225);
path.arcTo(400, 200, 600, 400, -180, 225, false);
path.lineTo(400, 542);
canvas.drawPath(path, paint);
return bitmap;
}
//椭圆
public static Bitmap getBitmapOval(int width, int height) {
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLACK);
canvas.drawOval(new RectF(0.0f, 0.0f, width, height), paint);
return bitmap;
}
}
源码在这里github喜欢的话,给个start哦~