Paint
- PorterDuffXfermode 两个图层交集区域显示方式,用的最多是DST_IN,SRC_IN显示圆形图片或圆角图片
圆角矩形
1
2
3
4
5
6
7
8
9
10
11
12private void drawRoundRect() {
ImageView roundRectIv = findViewById(R.id.roundRectIv);
Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.car3);
Bitmap mOut = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
PorterDuffXfermode mXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
Canvas canvas = new Canvas(mOut);
canvas.drawRoundRect(0, 0, mBitmap.getWidth(), mBitmap.getHeight(), 100, 100, mPaint);
mPaint.setXfermode(mXfermode);
canvas.drawBitmap(mBitmap, 0, 0, mPaint);
roundRectIv.setImageBitmap(mOut);
}- 刮刮卡
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40private void init() {
bgBmp = BitmapFactory.decodeResource(getResources(), R.mipmap.car3);
fgBmp = Bitmap.createBitmap(bgBmp.getWidth(), bgBmp.getHeight(), Bitmap.Config.ARGB_8888);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
//画路径时走透明通道,形成刮刮卡效果
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(50);
mCanvas = new Canvas(fgBmp);
mCanvas.drawColor(Color.GRAY);
mPath = new Path();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mPath.reset();
mPath.moveTo(x, y);
break;
case MotionEvent.ACTION_MOVE:
mPath.lineTo(x, y);
break;
}
mCanvas.drawPath(mPath, mPaint);
invalidate();
return true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(bgBmp, 0, 0, null);
canvas.drawBitmap(fgBmp, 0, 0, null);
}
Shader(着色器,渲染器)
1 | CLAMP 拉伸图片最后一个像素,不断重复 |
BitmapShader 位图shader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25圆形图片
private void init() {
bm = BitmapFactory.decodeResource(getResources(), R.mipmap.car3);
//图像填充功能
bitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.REPEAT);
mPaint = new Paint();
mPaint.setShader(bitmapShader);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
mLinearGradient=new LinearGradient(100,300,300,500, Color.RED,Color.YELLOW, Shader.TileMode.CLAMP);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(200, 200, 100, mPaint);
mPaint.setShader(mLinearGradient);
canvas.drawRect(100,300,300,500,mPaint);
}- LinearGradient 线性shader
- RadialGradient 光束shader
- SweepGradient 梯度shader
- ComposeShader 混合shader
图像倒影
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26private void init() {
mSrcBitmap= BitmapFactory.decodeResource(getResources(), R.mipmap.car3);
Matrix matrix=new Matrix();
//实项垂直翻转,(-1,1)实项水平翻转
matrix.setScale(1,-1);
mRefBitmap=Bitmap.createBitmap(mSrcBitmap,0,0,
mSrcBitmap.getWidth(),mSrcBitmap.getHeight(),matrix,true);
mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setShader(new LinearGradient(0,mSrcBitmap.getHeight(),
0,mSrcBitmap.getHeight()+mSrcBitmap.getHeight()/4,
0xdd000000,0x33000000, Shader.TileMode.CLAMP));
mXferMode=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(mXferMode);
canvas.drawRect(0,mSrcBitmap.getHeight(),mRefBitmap.getWidth(),
mSrcBitmap.getHeight()*2,mPaint);
mPaint.setXfermode(null);
}
PathEffect
- ComposePathEffect 先应用一种路径效果,再这个基础上混合另外一种效果
- CornerPathEffect 圆角路径
- DashPathEffect 虚线路径
- DiscretePathEffect 杂点路径
- PathDashPathEffect 设置点的图形路径效果
- SumPathEffect 组合两种路径后再应用到图形上
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31private void init() {
mEffects=new PathEffect[7];
mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(4);
mPath=new Path();
mPath.moveTo(0,0);
for (int i = 0; i <=30; i++) {
mPath.lineTo(i*35, (float) (Math.random()*100));
}
mEffects[0]=null;
mEffects[1]=new CornerPathEffect(30);
mEffects[2]=new DiscretePathEffect(5,3);
mEffects[3]=new DashPathEffect(new float[]{10,20,30,50},0);
Path path=new Path();
path.addRect(0,0,10,10, Path.Direction.CCW);
mEffects[4]=new PathDashPathEffect(path,12,0, PathDashPathEffect.Style.ROTATE);
mEffects[5]=new ComposePathEffect(mEffects[3],mEffects[1]);
mEffects[6]=new SumPathEffect(mEffects[3],mEffects[1]);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (PathEffect mEffect : mEffects) {
mPaint.setPathEffect(mEffect);
canvas.drawPath(mPath,mPaint);
canvas.translate(0,200);
}
}