自定义控件那些事儿 ----- 七【绘制Bitmap】

一、环境设置

本章节学习渲染Bitmap图片。定制展示效果的Demo。

1,创建自定义控件


/**
 * 自定义控件
 */

public class CustomView extends View {
    /**
     * 笔头设置
     */
    private Paint mPaint;
    /**
     * 绘图资源文件
     */
    private Bitmap bitmap;
    /**
     * 绘制图片左上角点坐标
     */
    private int x, y;

    public CustomView(Context context) {
        this(context, null);
    }

    public CustomView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
        initRes(context);
    }


    /**
     * 初始化画笔
     */
    private void initPaint() {
        // 实例化画笔并打开抗锯齿
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    /*
     *
     * 画笔样式分三种:
     * 1.Paint.Style.STROKE:描边
     * 2.Paint.Style.FILL_AND_STROKE:描边并填充
     * 3.Paint.Style.FILL:填充
     */
//        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);

        // 设置画笔颜色为浅灰色
        mPaint.setColor(Color.LTGRAY);

    /*
     * 设置描边的粗细,单位:像素px
     * 注意:当setStrokeWidth(0)的时候描边宽度并不为0而是只占一个像素
     */
        mPaint.setStrokeWidth(10);

        mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SCREEN));

    }


    /**
     * 初始化资源
     */
    private void initRes(Context context) {
        // 获取位图
        bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.eddie1);

        x = MainApplication.getApplication().getWidth() / 2 - bitmap.getWidth() / 2;
        y = MainApplication.getApplication().getHeight() / 2 - bitmap.getHeight() / 2;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 绘制圆环
        canvas.drawBitmap(bitmap, x, y, mPaint);

    }
}

2,引用并展示


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.future.customcontrolseconddemo.MainActivity">


    <com.future.customcontrolseconddemo.view.CustomView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />


</RelativeLayout>


public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

嗯哼哼,帅帅的Eddie应该是一个很好的榜样,偶像。




其中笔形设置有以下方法:




二、ColorFilter

1,ColorMatrix

修改initPaint()方法如下:

 /**
     * 初始化画笔
     */
    private void initPaint() {
        // 实例化画笔并打开抗锯齿
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    /*
     *
     * 画笔样式分三种:
     * 1.Paint.Style.STROKE:描边
     * 2.Paint.Style.FILL_AND_STROKE:描边并填充
     * 3.Paint.Style.FILL:填充
     */
//        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);

        // 设置画笔颜色为浅灰色
        mPaint.setColor(Color.LTGRAY);

    /*
     * 设置描边的粗细,单位:像素px
     * 注意:当setStrokeWidth(0)的时候描边宽度并不为0而是只占一个像素
     */
        mPaint.setStrokeWidth(10);


        // 生成色彩矩阵【原色】 --- 颜色变换
        ColorMatrix colorMatrix = new ColorMatrix(new float[]{
                1, 0, 0, 0, 0,
                0, 1, 0, 0, 0,
                0, 0, 1, 0, 0,
                0, 0, 0, 1, 0,
        });

        mPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));

    }

展示效果并没有变化啊!这是对的,因为设置的颜色矩阵是单位矩阵,也就是相当于没有做颜色变化。


        ColorMatrix colorMatrix = new ColorMatrix(new float[]{
                0.5F, 0, 0, 0, 0,
                0, 0.5F, 0, 0, 0,
                0, 0, 0.5F, 0, 0,
                0, 0, 0, 1, 0,
        });

展示效果:



黑白二值化:


        /**
         * 黑白二值化
         */
        ColorMatrix colorMatrix = new ColorMatrix(new float[]{
                0.33F, 0.59F, 0.11F, 0, 0,
                0.33F, 0.59F, 0.11F, 0, 0,
                0.33F, 0.59F, 0.11F, 0, 0,
                0, 0, 0, 1, 0,
        });



RB颜色交换:


        /**
         * RB颜色交换
         */
        ColorMatrix colorMatrix = new ColorMatrix(new float[]{
                0, 0, 1, 0, 0,
                0, 1, 0, 0, 0,
                1, 0, 0, 0, 0,
                0, 0, 0, 1, 0,
        });



2,LightingColorFilter -- 光照模式


        // 设置颜色过滤 --- 光照模式
        mPaint.setColorFilter(new LightingColorFilter(0xFFFF00FF, 0x00000000));
        //自然光,颜色不变
        mPaint.setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0x00000000));
        //只剩红色
        mPaint.setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0x00FF0000));
        //只剩黄色  ARGB
        mPaint.setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0x00FFFF00));

设置不同的光照模式,筛选只剩黄色的样式展示如图:



3,混合模式

        //设置混合模式 --- 混合模式
//        mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.DARKEN));
//        mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY));
        mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SCREEN));


红色混合图片展示效果如图:


混合有以下几种模式:



三、染色

染色模式有以下三种具体实现AvoidXfermode ,PixelXorXfermode,PorterDuffXfermode ,只是前两种在API16时就已经过时。


/**
 * 染色自定义控件 2017/12/6.
 */

public class AvoidXfermodeView extends View {

    private Paint mPaint;// 画笔
    private Context mContext;// 上下文环境引用
    private Bitmap bitmap;// 位图
//    private AvoidXfermode avoidXfermode;// AV模式[过时]
//    private PixelXorXfermode avoidXfermode;// AV模式[过时]
    private PorterDuffXfermode porterDuffXfermode;// AV模式

    private int x, y, w, h;// 位图绘制时左上角的起点坐标

    public AvoidXfermodeView(Context context) {
        this(context, null);
    }

    public AvoidXfermodeView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mContext = context;

        // 初始化画笔
        initPaint();

        // 初始化资源
        initRes(context);
    }

    private void initRes(Context context) {
        // 获取位图
        bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.eddie2);

        x = MainApplication.getApplication().getWidth() / 2 - bitmap.getWidth() / 2;
        y = MainApplication.getApplication().getHeight() / 2 - bitmap.getHeight() / 2;
        w = MainApplication.getApplication().getWidth() / 2 + bitmap.getWidth() / 2;
        h = MainApplication.getApplication().getHeight() / 2 + bitmap.getHeight() / 2;

    }

    private void initPaint() {
        // 实例化画笔
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        /*
         * 当画布中有跟0XFFFFFFFF色不一样的地方时候才“染”色
         */
//        avoidXfermode = new AvoidXfermode(0XFFFFFFFF, 0, AvoidXfermode.Mode.TARGET);
        porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.ADD);

    }

    public AvoidXfermodeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // 先绘制位图
        canvas.drawBitmap(bitmap, x, y, mPaint);

        // “染”什么色是由我们自己决定的
        mPaint.setARGB(255, 51, 200, 113);

        // 设置AV模式
        mPaint.setXfermode(porterDuffXfermode);

        // 画一个位图大小一样的矩形
        canvas.drawRect(x, y, w, h, mPaint);
    }
}

展示效果如图:



源码传送门


如果说岁月是年轮,我们便是推行者,如果说成长是一场华丽的蜕变,我们便是领舞者。一路走来,太多不易,告别青春的年少轻狂,我们成了岁月里被磨平的棱角,静静的守在属于自己的一亩三分地。



猜你喜欢

转载自blog.csdn.net/u013205623/article/details/78732623