码迷,mamicode.com
首页 > 其他好文 > 详细

Paint、Canvas、Matrix使用讲解(一、Paint)

时间:2015-03-18 18:00:24      阅读:389      评论:0      收藏:0      [点我收藏+]

标签:paint   canvas   matrix   安卓绘制   android动画   


好了,前面主要讲了Animation,Animator 的使用,以及桌面火箭效果和水波纹效果,分别使用android框架和自己绘制实现,俗话说,工欲善其事,必先利其器,接下来几篇文章主要讲绘制中我们需要常使用的一些利器;

Paint:画笔

Canvas:画布

Matrix:变换矩阵

绘制动效确实就像拿着笔在画布上面画画一样,而Paint就是我们拿着的笔,Canvas就是使用的画布;


一、Paint(画笔)

根据我们要画的类型,我们可以选择不同的笔,比如大气磅礴的山水画,我们可以选择大头的毛笔;细腻入微的肖像画我们可以选择尖头的铅笔。并且根据我们想要的效果,我们在绘画的时候,还会选择不同的颜料或不同颜色的笔;

那么在程序中,Paint 就足以满足以上所有的需要,我们可以根据我们自己的需要去自行设置我们画笔的属性,首先来看看都能设置哪些属性:


Paint 有三个构造函数,分别是:


Paint()创建一个画笔对象;

Paint(int flags):在构造的时候可以传入一些定义好的属性,eg:Paint.ANTI_ALIAS_FLAG  --用于绘制时抗锯齿

Paint(Paint paint):使用构造函数中Paint的属性生成一个新的Paint

    private void initPaint() {
        // 构建Paint时直接加上去锯齿属性
        mColorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        // 直接使用mColorPaint的属性构建mBitmapPaint
        mBitmapPaint = new Paint(mColorPaint);
    }

方法常用的主要有以下一些:


setARGB (int a, int r, int g, int b):用于设置画笔颜色,A 代表 alpha(透明度),R 代表Red (红色),G 代表 Green(绿色),B 代表 Blue(蓝色)

色值采用16进制,取值在 0 - 255 之间 ,0(0x00) 即 完全没有 ,255(0xff) 代表满值 ;

setAlpha(int a): 用于设置Paint 的透明度;

setColor(int color):同样设置颜色,如果是常用色,可以使用Color 类中定义好的一些色值 ,eg:Color.WHITE

setColorFilter(ColorFilter filter):设置颜色过滤器,可以通过颜色过滤器过滤掉对应的色值,比如去掉照片颜色,生成老照片效果;

ColorFilter有以下几个子类可用:

ColorMatrixColorFilter

LightingColorFilter

PorterDuffColorFilter


1.ColorMatrixColorFilter:通过颜色矩阵(ColorMatrix)对图像中的色值进行改变

在Android中,图片是以一个个RGBA的像素点的形式加载到内存中的,所以如果需要改变图片的颜色,就需要针对这一个个像素点的RGBA的值进行修改,其实主要是RGB,A是透明度;

修改图片RGBA的值需要ColorMatrix类的支持,它定义了一个5*4的float[]类型的矩阵,矩阵中每一行表示RGBA中的一个参数。

颜色矩阵M是以一维数组m=[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t]的方式进行存储的;

技术分享颜色矩阵


而对于一张图像来说,展示的颜色效果取决于图像的RGBA(红色、绿色、蓝色、透明度)值。而图像的RGBA值则存储在一个5*1的颜色分量矩阵C中,由颜色分量矩阵C可以控制图像的颜色效果。颜色分量矩阵如图所示:

技术分享

所以为了改变图像的显示效果,只需要改变5 *4 的颜色矩阵ColorMatrix,然后通过技术分享

即可得到新的图像显示矩阵;

由此可见,通过颜色矩阵 ColorMatrix 修改了原图像的RGBA值,从而达到了改变图片颜色效果的目的。并且,通过如上图所示的运算可知,颜色矩阵 ColorMatrix 的第一行参数abcde决定了图像的红色成分,第二行参数fghij决定了图像的绿色成分,第三行参数klmno决定了图像的蓝色成分,第四行参数pqrst决定了图像的透明度,第五列参数ejot是颜色的偏移量。

  通常,改变颜色分量时可以通过修改第5列的颜色偏移量来实现,如上面所示的颜色矩阵,通过计算后可以得知该颜色矩阵的作用是使图像的红色分量和绿色分量均增加100,这样的效果就是图片泛黄(因为红色与绿色混合后得到黄色):

技术分享

除此之外,也可以通过直接对颜色值乘以某一系数而达到改变颜色分量的目的。如下图所示的颜色矩阵,将绿色分量放大了2倍,这样的效果就是图片泛绿色:

技术分享

基于此,我们利用ColorFilter 和 ColorMatrixColorFilter类 和 Paint 的setColorFilter 就可以改变图片的展示效果(颜色,饱和度,对比度等),从而得到类似市面上图像软件中的黑白老照片、泛黄旧照片、羞涩的青春... ...特效;


技术分享     技术分享


上面的demo通过动态的改变上面颜色矩阵里的a、g、s、m 值,进而改变图像对应的色值分量,达到改变图片显示效果的目的:


    // 通过外层传入的 A、R、G、B值生成对应的ColorMatrix ,然后重新绘制图像
    public void setArgb(float alpha, float red, float green, float blue) {
        mRedFilter = red;
        mGreenFilter = green;
        mBlueFilter = blue;
        mAlphaFilter = alpha;
        mColorMatrix = new ColorMatrix(new float[] {
                mRedFilter, 0, 0, 0, 0,
                0, mGreenFilter, 0, 0, 0,
                0, 0, mBlueFilter, 0, 0,
                0, 0, 0, mAlphaFilter, 0,
        });
        mPaint.setColorFilter(new ColorMatrixColorFilter(mColorMatrix));

        postInvalidate();
    }


在Activity中拖动seekbar时,动态改变对应的色值参数,然后设置给里面的View:

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        float filter = (float) progress / 100;
        if (seekBar == mRedSeekBar) {
            mRedSeek = filter;
        } else if (seekBar == mGreenSeekBar) {
            mGreenSeek = filter;
        } else if (seekBar == mBlueSeekBar) {
            mBlueSeek = filter;
        } else if (seekBar == mAlphaSeekBar) {
            mAlphaSeek = filter;
        }
        mColorFilterView.setArgb(mAlphaSeek, mRedSeek, mGreenSeek, mBlueSeek);
    }


setDither(boolean dither):防抖动,这个属性的需求场景主要出现在绘制渐变色彩或含渐变的图片时,android对不含alpha通道的图片会进行一个转化,

成为RGB565 格式的,这种格式占用内存小,但因为如此,就会出现讨厌的“色带”情景,让人感觉过渡的不是那么柔和,针对这个问题,android提出了

防抖动,它会将原始颜色的过渡处根据两边的色值进行一些改变,从而让颜色过渡更加的柔和,让人觉得是平滑的过渡;

setFilterBitmap(boolean filter):如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加快显示速度

setFlags(int flags):可以用来给Paint设置里面定义好的一些属性,如抗锯齿,防抖动等;

setMaskFilter(MaskFilter maskFilter):设置绘制时图片边缘效果,可以有模糊和浮雕;

MaskFilter类可以为Paint分配边缘效果。
        对MaskFilter的扩展可以对一个Paint边缘的alpha通道应用转换。Android包含了下面几种MaskFilter:

        BlurMaskFilter   指定了一个模糊的样式和半径来处理Paint的边缘;
        EmbossMaskFilter  指定了光源的方向和环境光强度来添加浮雕效果;


setPathEffect(PathEffect effect):是用来控制绘制轮廓(线条)的方式。

PathEffect对于绘制Path基本图形特别有用,但是它们也可以应用到任何Paint中从而影响线条绘制的方式。
使用PathEffect,可以改变一个形状的边角的外观并且控制轮廓的外表。Android包含了多个PathEffect,包括:

CornerPathEffect :可以使用圆角来代替尖锐的角;

DashPathEffect  可以使用DashPathEffect来创建一个虚线的轮廓(短横线/小圆点),而不是使用实线。你还可以指定任意的虚/实线段的重复模式;

DiscretePathEffect  与DashPathEffect相似,但是添加了随机性。当绘制它的时候,需要指定每一段的长度和与原始路径的偏离度;

PathDashPathEffect  这种效果可以定义一个新的形状(路径)并将其用作原始路径的轮廓标记;

下面的效果可以在一个Paint中组合使用多个Path Effect:

SumPathEffect  顺序地在一条路径中添加两种效果,这样每一种效果都可以应用到原始路径中,而且两种结果可以结合起来;

ComposePathEffect  将两种效果组合起来应用,先使用第一种效果,然后在这种效果的基础上应用第二种效果;

对象形状的PathEffect的改变会影响到形状的区域。这就能够保证应用到相同形状的填充效果将会绘制到新的边界中;


setShader(Shader shader)

设置图像效果,使用Shader可以绘制出各种渐变效果;

Shader下面有五个子类可用:

BitmapShader :位图渲染

LinearGradient:线性渐变

RadialGradient:中心渐变

SweepGradient:扫描渐变

ComposeGradient:


setShadowLayer(float radius ,float dx,float dy,int color):在图形下面设置阴影层,产生阴影效果,radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色

setStyle(Paint.Style style):设置画笔的样式,为FILL,FILL_OR_STROKE,或STROKE

setStrokeCap(Paint.Cap cap):当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式,如圆形样式;

Cap.ROUND,或方形样式Cap.SQUARE 

setSrokeJoin(Paint.Join join):设置绘制时各图形的结合方式,如平滑效果等;

setStrokeWidth(float width):当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度;

setXfermode(Xfermode xfermode)设置图形重叠时的处理方式,如合并,取交集或并集;


Text文本绘制相关:


setFakeBoldText(boolean fakeBoldText)模拟实现粗体文字,设置在小字体上效果会非常差;

setSubpixelText(boolean subpixelText)设置该项为true,它可以保证在绘制斜线的时候使用抗锯齿效果来平滑该斜线的外观;

setTextAlign(Paint.Align align)设置绘制文字的对齐方向;

setTextScaleX(float scaleX)设置绘制文字x轴的缩放比例,可以实现文字的拉伸的效果;

setTextSize(float textSize)设置绘制文字的字号大小;

setTextSkewX(float skewX)设置斜体文字,skewX为倾斜弧度;

setTypeface(Typeface typeface)设置Typeface对象,即字体风格,包括粗体,斜体以及衬线体,非衬线体等;

setUnderlineText(boolean underlineText)设置带有下划线的文字效果;

setStrikeThruText(boolean strikeThruText)设置带有删除线的效果;












Paint、Canvas、Matrix使用讲解(一、Paint)

标签:paint   canvas   matrix   安卓绘制   android动画   

原文地址:http://blog.csdn.net/tianjian4592/article/details/44336949

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!