Android---绘图机制---画笔特效处理

PorterDuffXfermode

PorterDuffXfermode的16种使用模式
Android---绘图机制---画笔特效处理_第1张图片
以下代码实现的就是一个通过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);
    }
}

效果图:
Android---绘图机制---画笔特效处理_第2张图片

这里唯一要注意的就是使用PorterDuffXfermode的时候最好把硬件加速给关掉,因为有些不支持

Shader

Shader又被称为着色器。渲染器,它可以实现渲染,渐变等效果,Android中的Shader包括以下几种

  • BitmapShader—-位图Shader
  • LinearGradient— 线性Shader
  • RadialGradient— 光束Shader
  • SweepGradient—梯形Shader
  • ComposeShader–混合Shader

在这里比较特殊的就是BitmapShader 他的作用就是通过Paint对画布进行Bitmap填充 填充有以下几种模式供选择

  • CLAMP拉伸——拉伸的是图片最后的哪一个像素,不断重复
  • REPEAT重复——横向,纵向不断重复
        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);

    }

Android---绘图机制---画笔特效处理_第3张图片

实现一个图片倒影效果

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);

    }
}

Android---绘图机制---画笔特效处理_第4张图片

PathEffect

如下图所示,直观的理解PathEffect.
Android---绘图机制---画笔特效处理_第5张图片
PathEffect就是指用各种笔触效果绘制一个路径.
有如下几种方法:

  • CornerPathEffect:拐弯处变圆滑,圆滑指数由参数定
  • DiscretePathEffect 线段上有杂点
  • DashPathEffect:用来绘制虚线,用一个数组来设置各个点之间的间隔,phase控制绘制时候数组的一个偏移量 来实现路径的动态效果
  • PathDashPathEffect:杂点可以设置形状
  • ComposePathEffect:通过组合显示一个新的效果
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);
        }
    }
}

Android---绘图机制---画笔特效处理_第6张图片

你可能感兴趣的:(Android--绘图机制)