0917Android基础自定义View(颜色渲染PorterDuff及Xfermode)

来源:互联网 发布:淘宝新店如何运营 编辑:程序博客网 时间:2024/06/04 19:14

颜色渲染

  补充基础知识请点我http://blog.csdn.net/t12x3456/article/details/10432935

颜色渲染实例1

  新建一个类继承View,继承他的俩构造器和onDraw以及onMeasure方法。PorterDuff必须画在bitmap上。步骤:

  • 创建一个位图
//      创建一个宽with高height的新位图,第三个参数传位图配置,这里的配置意思为:每个像素被存储在4个字节中。        mBitmap=Bitmap.createBitmap(mWith,mHeight, Bitmap.Config.ARGB_8888);
  • 绘制一个由该位图构成的画布(自定义)
//        绘制一个由指定位图构成的画布        canvasBit=new Canvas(mBitmap);
  • 设置渲染方式
//        可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互        PorterDuffXfermode mode=new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);        mPaintSrc.setXfermode(mode);
  • 在自定义画布上对位图进行渲染操作,注意是那个画笔调用了setXfermode方法
//        图像渲染只能在bitmap中进行,通过canvasBit对bitmap进行渲染操作        canvasBit.drawCircle(mWith / 2, mHeight / 2, 250, mPaintDst);        canvasBit.drawRect(10, 200, mWith/2, mHeight/2, mPaintSrc);
  • 在onDraw中的画布中将已经进行渲染操作的位图画在画布上。
//        将位图放在画布中,在进行了渲染操作的位图放到画布中显示出来。        canvas.drawBitmap(mBitmap,0,0,null);

该实例的效果图(PorterDuff.Mode.SRC_OVER)

这里写图片描述

参考:API中提供的能够进行的16中操作种类(PorterDuff.Mode为枚举类,一共有16个枚举值)
这里写图片描述
1.PorterDuff.Mode.CLEAR
所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC
显示上层绘制图片
3.PorterDuff.Mode.DST
显示下层绘制图片
4.PorterDuff.Mode.SRC_OVER
正常绘制显示,上下层绘制叠盖。
5.PorterDuff.Mode.DST_OVER
上下层都显示。下层居上显示。
6.PorterDuff.Mode.SRC_IN
取两层绘制交集。显示上层。
7.PorterDuff.Mode.DST_IN
取两层绘制交集。显示下层。
8.PorterDuff.Mode.SRC_OUT
取上层绘制非交集部分。
9.PorterDuff.Mode.DST_OUT
取下层绘制非交集部分。
10.PorterDuff.Mode.SRC_ATOP
取下层非交集部分与上层交集部分
11.PorterDuff.Mode.DST_ATOP
取上层非交集部分与下层交集部分
12.PorterDuff.Mode.XOR
异或:去除两图层交集部分
13.PorterDuff.Mode.DARKEN
取两图层全部区域,交集部分颜色加深
14.PorterDuff.Mode.LIGHTEN
取两图层全部,点亮交集部分颜色
15.PorterDuff.Mode.MULTIPLY
取两图层交集部分叠加后颜色
16.PorterDuff.Mode.SCREEN
取两图层全部区域,交集部分变为透明色

全部代码

import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.util.AttributeSet;import android.view.View;import com.example.laowang.android0916canvas_.R;/** * Created by Administrator on 2015/9/17. */public class MyBitmapView2 extends View {    private int mWith;    private int mHeight;    private Paint mPaintSrc;    private Paint mPaintDst;    private Bitmap mBitmap;    private Canvas canvasBit;    public MyBitmapView2(Context context) {        super(context);    }    public MyBitmapView2(Context context, AttributeSet attrs) {        super(context, attrs);//        初始化bitmap对象        mBitmap= BitmapFactory.decodeResource(getResources(), R.mipmap.dogno);        mPaintSrc=new Paint();        mPaintDst=new Paint();        mPaintSrc.setColor(Color.argb(0xff, 0x63, 0xAA, 0xFF));//自定义颜色        mPaintSrc.setAntiAlias(true);        mPaintDst.setColor(Color.argb(0xff, 0xFF, 0xCF, 0x42));        mPaintDst.setAntiAlias(true);//        可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互        PorterDuffXfermode mode=new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);        mPaintSrc.setXfermode(mode);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mWith = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);        mHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);        setMeasuredDimension(mWith, mHeight);//      创建一个宽with高height的新位图,第三个参数传位图配置,这里的配置意思为:每个像素被存储在4个字节中。        mBitmap=Bitmap.createBitmap(mWith,mHeight, Bitmap.Config.ARGB_8888);//        绘制一个由指定位图构成的画布        canvasBit=new Canvas(mBitmap);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawColor(Color.GRAY);//        图像渲染只能在bitmap中进行,通过canvasBit对bitmap进行渲染操作        canvasBit.drawCircle(mWith / 2, mHeight / 2, 250, mPaintDst);        canvasBit.drawRect(10, 200, mWith/2, mHeight/2, mPaintSrc);//        将位图放在画布中,在进行了渲染操作的位图放到画布中显示出来。        canvas.drawBitmap(mBitmap,0,0,null);    }}

颜色渲染实例2

  在实例1的基础上面加以修改,达到这个效果,鼠标按下后拖动将蓝色部分去掉,点击保存照片将照片保存。
  
这里写图片描述
  
  首先添加权限

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

  创建一个Bitmap背景对象,在构造器中初始化。

      mBitmapBackground=BitmapFactory.decodeResource(getResources(),R.mipmap.nurse);

  在onMeasure方法中获得他的宽高

        mImageWith = mBitmapBackground.getWidth();        mImageHeight = mBitmapBackground.getHeight();

  设置画笔移动时的效果!!!!!!

        mPaintDst.setAntiAlias(true);//        可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互        PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.XOR);        mPaintDst.setXfermode(mode);//mPaintDst加上以后加图片处理,所以后面话圆的时候要用这个画笔        mPaintDst.setStrokeJoin(Paint.Join.ROUND);//圆角 连接时使用的方式        mPaintDst.setStrokeCap(Paint.Cap.ROUND);//圆角 覆盖式使用的方式        mPaintDst.setStyle(Paint.Style.STROKE);//要用上面的方法必须将画笔设置成STROKE或者FILL_AND_STROKE

  将背景图片添加到画布中,通过path画出线条

    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);//        添加背景图片,拉伸到屏幕大小        canvas.drawBitmap(mBitmapBackground, new Rect(0, 0, mImageWith, mImageHeight), new Rect(0, 0, mWith, mHeight), null);//        图像渲染只能在bitmap中进行,通过canvasBit对bitmap进行渲染操作//        canvasBit.drawCircle(mWith / 2, mHeight / 2, 250, mPaintDst);        canvasBit.drawRect(0, 0, mWith, mHeight, mPaintSrc);//先画底层的//             通过Path实现画多个圆,不取消前面画的圆        canvasBit.drawPath(mPath, mPaintDst);//        将位图放在画布中,在进行了渲染操作的位图放到画布中显示出来。        canvas.drawBitmap(mBitmap, 0, 0, null);    }

  添加touch效果

   @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                x = event.getX();                y = event.getY();                mPath.moveTo(x, y);                invalidate();//刷新                old_x = x;                old_y = y;                return true;            case MotionEvent.ACTION_MOVE:                x = event.getX();                y = event.getY();                mPath.moveTo(old_x, old_y);                mPath.lineTo(x, y);                invalidate();                old_y = y;                old_x = x;                return true;            case MotionEvent.ACTION_UP:                break;            default:                break;        }        return super.onTouchEvent(event);    }

  
这里写图片描述

修改后的代码

package com.example.laowang.myview2;import android.content.Context;import android.content.res.TypedArray;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.graphics.Rect;import android.graphics.drawable.BitmapDrawable;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;/** * Created by Administrator on 2015/9/18. */public class MyBitmapView extends View {    private int mWith;    private int mHeight;    private Paint mPaintSrc;    private Paint mPaintDst;    private Bitmap mBitmap;    private Bitmap mBitmapBackground;    private Canvas canvasBit;    private int mImageWith;    private int mImageHeight;    private Path mPath;    private float x;    private float y;    private float old_y;    private float old_x;    public MyBitmapView(Context context) {        super(context);    }    public MyBitmapView(Context context, AttributeSet attrs) {        super(context, attrs);        mPath = new Path();        mPaintSrc = new Paint();        mPaintDst = new Paint();        mPaintSrc.setColor(Color.argb(0xff, 0x63, 0xAA, 0xFF));//自定义颜色        mPaintSrc.setAntiAlias(true);        mPaintDst.setColor(Color.argb(0xff, 0xFF, 0xCF, 0x42));        mPaintDst.setStrokeWidth(30);        mPaintDst.setAntiAlias(true);//        可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互        PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.XOR);        mPaintDst.setXfermode(mode);//mPaintDst加上以后加图片处理,所以后面话圆的时候要用这个画笔        mPaintDst.setStrokeJoin(Paint.Join.ROUND);//圆角 连接时使用的方式        mPaintDst.setStrokeCap(Paint.Cap.ROUND);//圆角 覆盖式使用的方式        mPaintDst.setStyle(Paint.Style.STROKE);//要用上面的方法必须将画笔设置成STROKE或者FILL_AND_STROKE//        背景图片      mBitmapBackground=BitmapFactory.decodeResource(getResources(),R.mipmap.dog);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mWith = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);        mHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);        setMeasuredDimension(mWith, mHeight);//      创建一个宽with高height的新位图,第三个参数传位图配置,这里的配置意思为:每个像素被存储在4个字节中。        mBitmap = Bitmap.createBitmap(mWith, mHeight, Bitmap.Config.ARGB_8888);//        绘制一个由指定位图构成的画布        canvasBit = new Canvas(mBitmap);        mImageWith = mBitmapBackground.getWidth();        mImageHeight = mBitmapBackground.getHeight();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);//        添加背景图片,拉伸到屏幕大小        canvas.drawBitmap(mBitmapBackground, new Rect(0, 0, mImageWith, mImageHeight), new Rect(0, 0, mWith, mHeight), null);//        图像渲染只能在bitmap中进行,通过canvasBit对bitmap进行渲染操作//        canvasBit.drawCircle(mWith / 2, mHeight / 2, 250, mPaintDst);        canvasBit.drawRect(0, 0, mWith, mHeight, mPaintSrc);//先画底层的//             通过Path实现画多个圆,不取消前面画的圆        canvasBit.drawPath(mPath, mPaintDst);//        将位图放在画布中,在进行了渲染操作的位图放到画布中显示出来。        canvas.drawBitmap(mBitmap, 0, 0, null);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                x = event.getX();                y = event.getY();                mPath.moveTo(x, y);                invalidate();//刷新                old_x = x;                old_y = y;                return true;            case MotionEvent.ACTION_MOVE:                x = event.getX();                y = event.getY();                mPath.moveTo(old_x, old_y);                mPath.lineTo(x, y);                invalidate();                old_y = y;                old_x = x;                return true;            case MotionEvent.ACTION_UP:                break;            default:                break;        }        return super.onTouchEvent(event);    }}
0 0
原创粉丝点击