PorterDuffXfermode的16种使用模式
以下代码实现的就是一个通过SrcIn模式设计的一个圆角的图片.
public void initView() {
mBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.img);
mOut = Bitmap.createBitmap(mBitmap.getWidth(),
mBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(mOut);
mPaint = new Paint();
mPaint.setAntiAlias(true);
canvas.drawRoundRect(0, 0,
mBitmap.getWidth(),
mBitmap.getHeight(), 80, 80, mPaint);
mPaint.setXfermode(new PorterDuffXfermode(
PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(mBitmap, 0, 0, mPaint);
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mOut, 0, 0, null);
}
一个刮刮卡效果的图片
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class XfermodeView extends View {
private Bitmap mBgBitmap, mFgBitmap;
private Paint mPaint;
private Canvas mCanvas;
private Path mPath;
public XfermodeView(Context context) {
super(context);
init();
}
public XfermodeView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public XfermodeView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setAlpha(0);
mPaint.setXfermode(
new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setStyle(Paint.Style.STROKE);
//让画笔和连接处更圆滑一些
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeWidth(200);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPath = new Path();
mBgBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.zc);
mFgBitmap = Bitmap.createBitmap(mBgBitmap.getWidth(),
mBgBitmap.getHeight(), Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mFgBitmap);
mCanvas.drawColor(Color.GRAY);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mPath.reset();
mPath.moveTo(event.getX(), event.getY());
break;
case MotionEvent.ACTION_MOVE:
mPath.lineTo(event.getX(), event.getY());
break;
}
mCanvas.drawPath(mPath, mPaint);
invalidate();
return true;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mBgBitmap, 0, 0, null);
canvas.drawBitmap(mFgBitmap, 0, 0, null);
}
}
这里唯一要注意的就是使用PorterDuffXfermode的时候最好把硬件加速给关掉,因为有些不支持
Shader又被称为着色器。渲染器,它可以实现渲染,渐变等效果,Android中的Shader包括以下几种
在这里比较特殊的就是BitmapShader 他的作用就是通过Paint对画布进行Bitmap填充 填充有以下几种模式供选择
mBitmap= BitmapFactory.decodeResource(getResources(),R.drawable.dog);
mBitmapShader1=new BitmapShader(mBitmap,
android.graphics.Shader.TileMode.REPEAT, android.graphics.Shader.TileMode.REPEAT);
mPaint1=new Paint();
mPaint1.setShader(mBitmapShader1);
mBitmapShader2=new BitmapShader(mBitmap,
android.graphics.Shader.TileMode.CLAMP, android.graphics.Shader.TileMode.CLAMP);
mPaint2=new Paint();
mPaint2.setShader(mBitmapShader2);
mBitmapShader3=new BitmapShader(mBitmap,
android.graphics.Shader.TileMode.MIRROR, android.graphics.Shader.TileMode.MIRROR);
mPaint3=new Paint();
mPaint3.setShader(mBitmapShader3);
LinearGradient线性渐变
mPaint=new Paint();
mPaint.setShader(new LinearGradient(0,0,400,400, Color.BLUE,Color.YELLOW,
Shader.TileMode.REPEAT));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(0,0,800,800,mPaint);
}
实现一个图片倒影效果
public class Reflect extends View {
private Bitmap mSrcBitmap,mRefBitmap;
private PorterDuffXfermode xfermode;
private Paint mPaint1,mPaint2,mPaint3,mPaint;
public Reflect(Context context, AttributeSet attrs) {
super(context, attrs);
mSrcBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.dog);
Matrix matrix=new Matrix();
//实现垂直翻转
matrix.setScale(1F,-1F);
mRefBitmap=Bitmap.createBitmap(mSrcBitmap,0,0,
mSrcBitmap.getWidth(),mSrcBitmap.getHeight(),matrix,true);
mPaint=new Paint();
mPaint.setShader(new LinearGradient(0,mSrcBitmap.getHeight(),0,mSrcBitmap.getHeight()+mSrcBitmap.getHeight()/4,
0XDD000000,0X10000000,
Shader.TileMode.CLAMP));
xfermode=new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(mSrcBitmap,0,0,null);
canvas.drawBitmap(mRefBitmap,0,mSrcBitmap.getHeight(),null);
mPaint.setXfermode(xfermode);
//绘制渐变效果矩形
canvas.drawRect(0,mSrcBitmap.getHeight(),
mRefBitmap.getWidth(),mSrcBitmap.getHeight()*2,mPaint);
mPaint.setXfermode(null);
}
}
如下图所示,直观的理解PathEffect.
PathEffect就是指用各种笔触效果绘制一个路径.
有如下几种方法:
public class PathEffectView extends View {
private Paint mPaint;
private Path mPath;
private PathEffect[] mEffects;
public PathEffectView(Context context, AttributeSet attrs) {
super(context, attrs);
//new一个画笔并设置颜色
mPaint = new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
mPaint.setColor(Color.DKGRAY);
mPath = new Path();
//绘制一个随机的路径
mPath.moveTo(0, 0);
for (int i = 0; i <= 30; i++) {
mPath.lineTo(i * 35, (float) (Math.random() * 100));
}
mEffects = new PathEffect[6];
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mEffects[0] = null;
mEffects[1] = new CornerPathEffect(30);
mEffects[2] = new DiscretePathEffect(3.0F, 5.0F);
mEffects[3] = new DashPathEffect(new float[]{20, 10, 5, 10}, 0);
Path path = new Path();
path.addRect(0, 0, 8, 8, Path.Direction.CCW);
mEffects[4] = new PathDashPathEffect(path, 12, 0, PathDashPathEffect.Style.ROTATE);
mEffects[5] = new ComposePathEffect(mEffects[3], mEffects[1]);
for (int i = 0; i < mEffects.length; i++) {
mPaint.setPathEffect(mEffects[i]);
canvas.drawPath(mPath, mPaint);
canvas.translate(0, 200);
}
}
}