Android PorterDuff.Mode与Canvas实际使用
转载请注明出处:
http://blog.csdn.net/u014163726?viewmode=contents
本文出自Wrh的博客
Canvas
简单翻译一下:
Canvas可以理解为画布的概念
在画布上作画需要:bitmap,canvas,内容,paint
了解了大概我们先简单的画几个东西出来
public class MyTestView extends View {
private Paint mPaint;
public MyTestView(Context context) {
this(context, null);
}
public MyTestView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyTestView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
private void initPaint(){
mPaint = new Paint();
mPaint.setColor(Color.BLUE);
mPaint.setStrokeWidth(5);
mPaint.setAntiAlias(true);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawRect(getWidth()/2 -300,getHeight()/2-300,getWidth()/2+300,getHeight()/2+300,mPaint);
}
}
自定View在其onDraw中使用canvas.drawRect绘制了一个矩形,这是常规情况,如果我们再绘制一个矩形呢
mPaint.setColor(Color.GREEN);
canvas.drawRect(getWidth()/2 -250,getHeight()/2-250,getWidth()/2+350,getHeight()/2+350,mPaint);
效果如下
我们可以看到后绘制的绿色矩形覆盖在了先绘制的蓝色矩形上,这也是符合常理的,但有时候我们会有一些需求或者功能的实现,需要特殊绘制
PorterDuff.Mode
已有的图像上绘图
简单来说PorterDuff.Mode有这么多模式,具体含义可能要参考ApiDemo那张经典老图
图中是先绘制的Dst也是就是黄色的后绘制Src,基本的东西我们了解了接下来就要动手实践了
- 如何使用PorterDuff.Mode
使用的话可以用Paint中的set方法
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XXX));
我们可能会理所当然的这样使用
canvas.drawRect(getWidth()/2 -300,getHeight()/2-300,getWidth()/2+300,getHeight()/2+300,mPaint);
mPaint.setColor(Color.GREEN);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));
canvas.drawRect(getWidth()/2 -250,getHeight()/2-250,getWidth()/2+350,getHeight()/2+350,mPaint);
但是这样是起不到我们想要的效果的,我们要注意是已有的图像上绘图!所以我们如果这样改一下代码。
private void init(){
mPaint = new Paint();
mPaint.setColor(Color.GREEN);
mPaint.setStrokeWidth(5);
mPaint.setAntiAlias(true);
mBitmap = Bitmap.createBitmap(600,600, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
mPaint.setColor(Color.BLUE);
canvas.drawBitmap(mBitmap, getWidth() / 2 - 300, getHeight() / 2 - 300,null);
mCanvas.drawRect(0, 0, 450, 450, mPaint);
mPaint.setColor(Color.GREEN);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));
mCanvas.drawRect(50, 50, 500, 500, mPaint);
}
可以看到我们依然是先绘制了蓝色再绘制绿色,但是结果却变成了蓝色在上。
在代码中我们没有使用canvas.drawRect来绘制矩形,因为我们要在已有的图像上绘图,所以我们自己创建了一个bitmap,用canvas.drawBitmap绘制到控件上,而在bitmap中,我们使用mCanvas来选择绘制的模式。
- 简单的灵活运用
我以前写的一篇Android 仿qq上传头像(一)当中也使用了一种绘制方式,但是讲解的不够详细,这次我们就来详细的实现半透明圆形遮罩层功能
1.首先确定要使用的绘制模式
2.创建一个照片Bitmap再创建一个遮罩层Bitmap
3.中心的圆形透明
中心透明的遮罩层,我们可以采用DstOut这种模式,这种模式把交集的部分透明。
private void init(){
mPaint = new Paint();
mPaint.setStrokeWidth(5);
mPaint.setAntiAlias(true);
mImgBitmap = BitmapFactory.decodeResource(this.getContext().getResources(), R.mipmap.xiangrikui);
imgWidth = mImgBitmap.getWidth();
imgHeight = mImgBitmap.getHeight();
mBitmap = Bitmap.createBitmap(imgWidth, imgHeight, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mCanvas.drawColor(getResources().getColor(R.color.black));
}
@Override
protected void onDraw(Canvas canvas) {
canvas.translate(getWidth()/2 - imgWidth/2,getHeight()/2 - imgHeight/2);
canvas.drawBitmap(mImgBitmap, 0, 0, null);
canvas.drawBitmap(mBitmap,0,0,null);
}
现在我们就绘制了一个半透明的遮罩层,下来我们透明中心区域采用DstOut模式
@Override
protected void onDraw(Canvas canvas) {
canvas.translate(getWidth() / 2 - imgWidth / 2, getHeight() / 2 - imgHeight / 2);
canvas.drawBitmap(mImgBitmap, 0, 0, null);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
mCanvas.drawCircle(imgWidth / 2,imgHeight / 2,100,mPaint);
canvas.drawBitmap(mBitmap,0,0,null);
}
很简单不是么,Bye。
推荐个博客 毅神