自定义控件点滴2(setColorFilter)

画笔设置属性疑难1:

setColorFilter(ColorFilter filter)
设置颜色过滤,就像拿个筛子把颜色“滤”一遍获取我们想要的色彩结果
ColorFilter没有做具体的实现,但是其有三个子类,设置时传入其三个子类中的一个即可。

ColorFilter的三个子类为:ColorMatrixColorFilter、LightingColorFilter和PorterDuffColorFilter,我们具体说明每个子类的用法。

ColorMatrixColorFilter的用法:

中文直译为色彩矩阵颜色过滤器,要明白这玩意你得先了解什么是色彩矩阵。在Android中图片是以RGBA像素点的形式加载到内存中的,修改这些像素信息需要一个叫做ColorMatrix类的支持,其定义了一个4x5的float[]类型的矩阵:

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

其中,第一行表示的R(红色)的向量,第二行表示的G(绿色)的向量,第三行表示的B(蓝色)的向量,最后一行表示A(透明度)的向量,这一顺序必须要正确不能混淆!这个矩阵不同的位置表示的RGBA值,其范围在0.0F至2.0F之间,1为保持原图的RGB值。每一行的第五列数字表示偏移值,何为偏移值?顾名思义当我们想让颜色更倾向于红色的时候就增大R向量中的偏移值,想让颜色更倾向于蓝色的时候就增大B向量中的偏移值,这是最最朴素的理解,但是事实上色彩偏移的概念是基于白平衡来理解的,什么是白平衡呢?
在正常情况下白色是(255, 255, 255, 255)但是现实世界中我们是无法找到这样的纯白物体的,所以在我们用单反拍照之前就会拿一个我们认为是白色的物体让相机记录这个物体的颜色作为白色,然后拍摄时整张照片的颜色都会依据这个定义的白色来偏移!而这个我们定义的“白色”(比如:255, 253, 251, 247)和纯白(255, 255, 255, 255)之间的偏移值(0, 2, 4, 8)我们称之为白平衡的色彩偏移。

使用代码:

public class CustomView extends View{
private Paint myPaint,paint;
private Context mContext;// 上下文环境引用  
private Bitmap bitmap;// 位图  
    public CustomView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        mContext=context;
        initPaint();
           //初始化资源  
        initRes(context);  
    }
@Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        canvas.drawBitmap(bitmap, 1, 1, myPaint);

        canvas.drawBitmap(bitmap, 0, bitmap.getHeight()+30, paint);
    }
    private void initRes(Context context) {
        // TODO Auto-generated method stub
          // 获取位图  
        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.a);  
    }

    private void initPaint() {
        // TODO Auto-generated method stub
        myPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
        paint=new Paint(Paint.ANTI_ALIAS_FLAG);
        // 生成色彩矩阵  
        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,  
        });  
        myPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));  
    }

}

LightingColorFilter的使用

顾名思义光照颜色过滤,这肯定是跟光照是有关的了~~该类有且只有一个构造方法:

LightingColorFilter (int mul, int add)  

这个方法非常非常地简单!mul全称是colorMultiply意为色彩倍增,而add全称是colorAdd意为色彩添加,这两个值都是16进制的色彩值0xAARRGGBB。

比如我们想要去掉绿色:

mPaint.setColorFilter(new LightingColorFilter(0xFFFF00FF, 0x00000000));

运行后你会发现绿色确实是没了但是原来偏绿的部分现在居然成了红色,为毛!敬请关注下一系列设计色彩文章!!哈哈哈!!当LightingColorFilter(0xFFFFFFFF, 0x00000000)的时候原图是不会有任何改变的,如果我们想增加红色的值,那么LightingColorFilter(0xFFFFFFFF, 0x00XX0000)就好,其中XX取值为00至FF。那么这个方法有什么存在的意义呢?存在必定合理,这个方法存在一定是有它可用之处的,前些天有个盆友在群里问点击一个图片如何直接改变它的颜色而不是为他多准备另一张点击效果的图片,这种情况下该方法就派上用场了!

自定义控件的点击事件:

public class CustomView extends View{
private Paint myPaint,paint;
private Context mContext;// 上下文环境引用  
private Bitmap bitmap;// 位图  
private boolean isClick=false;
    public CustomView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        mContext=context;
        initPaint();
           //初始化资源  
        initRes(context);  
        setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                  /* 
                 * 判断控件是否被点击过 
                 */  
                if (isClick) {  
                    // 如果已经被点击了则点击时设置颜色过滤为空还原本色  
                    paint.setColorFilter(null);  
                    isClick = false;  
                } else {  
                    // 如果未被点击则点击时设置颜色过滤后为黄色  
                    paint.setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0X00FFFF00));  
                    isClick = true;  
                }  

                // 记得重绘  
                invalidate();
            }
        });
    }
@Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        canvas.drawBitmap(bitmap, 1, 1, myPaint);

        canvas.drawBitmap(bitmap, 0, bitmap.getHeight()+30, paint);
    }
    private void initRes(Context context) {
        // TODO Auto-generated method stub
          // 获取位图  
        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.a);  
    }

    private void initPaint() {
        // TODO Auto-generated method stub
        myPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
        paint=new Paint(Paint.ANTI_ALIAS_FLAG);
        //颜色过滤
        paint.setColorFilter(new LightingColorFilter(0xFFFF00FF, 0x00000000));
        // 生成色彩矩阵  
        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,  
        });  
        myPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));  
    }

}

PorterDuffColorFilter的使用:

PorterDuffColorFilter跟LightingColorFilter一样,只有一个构造方法:

PorterDuffColorFilter(int color, PorterDuff.Mode mode) 

这个构造方法也接受两个值,一个是16进制表示的颜色值这个很好理解,而另一个是PorterDuff内部类Mode中的一个常量值,这个值表示混合模式。那么什么是混合模式呢?混合混合必定是有两种东西混才行,第一种就是我们设置的color值而第二种当然就是我们画布上的元素了!,比如这里我们把Color的值设为红色,而模式设为PorterDuff.Mode.DARKEN变暗:

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

当然PorterDuff.Mode还有其他很多的混合模式,大家可以尝试,但是这里要注意一点,PorterDuff.Mode中的模式不仅仅是应用于图像色彩混合,还应用于图形混合,比如PorterDuff.Mode.DST_OUT就表示裁剪混合图,如果我们在PorterDuffColorFilter中强行设置这些图形混合的模式将不会看到任何对应的效果,关于图形混合我们将在下面详解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值