Paint的详解

在Paint中有很多的属性可以设置,比如可以设置阴影,颜色过滤等等,这些会产生不同的奇妙效果,今天就对各种属性探索一下。
方法一:
1 //设置绘制的颜色,a代表透明度,r,g,b代表颜色值。 2 setARGB(int a,int r,int g,int b);

这个不多说了,还有两个类似的方法,将设置alpha和rgb分割开来了。注意的是这里的a值是0~255的范围,不是小数。
方法二:
//设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。setAntiAlias(boolean aa);

也不多说,你可以试验一下效果,设置后会平滑一些;
方法三:
1 //设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰 2 setDither(boolean dither);

方法四:
1 //设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等 2 setMaskFilter(MaskFilter maskfilter);

MaskFilter类可以为Paint分配边缘效果。对MaskFilter的扩展可以对一个Paint边缘的alpha通道应用转换。Android包含了下面几种MaskFilter:BlurMaskFilter 指定了一个模糊的样式和半径来处理Paint的边缘。EmbossMaskFilter 指定了光源的方向和环境光强度来添加浮雕效果。要应用一个MaskFilter,可以使用setMaskFilter方法,并传递给它一个MaskFilter对象。下面的例子是对一个已经存在的Paint应用一个EmbossMaskFilter:


复制代码

1 // 设置光源的方向 2 float[] direction = new float[]{ 1, 1, 1 }; 3 4 //设置环境光亮度 5 float light = 0.4f; 6 7 // 选择要应用的反射等级 8 float specular = 6; 9 10 // 向mask应用一定级别的模糊11 float blur = 3.5f;12 13 EmbossMaskFilter emboss=new EmbossMaskFilter(direction,light,specular,blur);14 15 // 应用mask 16 myPaint.setMaskFilter(emboss);


复制代码

可以看一下下面的图,是不是有浮雕的效果??



再看下面使用BlurMaskFilter:
1 //前面一个控制阴影的宽度,后面一个参数控制阴影效果2 maskFilter = new BlurMaskFilter(10, BlurMaskFilter.Blur.SOLID);


是不是有阴影效果呢??
方法五:
1 //设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果2 setColorFilter(ColorFilter colorfilter);

这个方法也值得试验一下:
MaskFilter是对一个Paint的alpha通道的转换,而ColorFilter则是对每一个RGB通道应用转换。所有由ColorFilter所派生的类在执行它们的转换时,都会忽略alpha通道。
这个貌似比较麻烦,改天再说。
方法六:
1 //设置绘制路径的效果,如点画线等2 setPathEffect(PathEffect effect);

又是一个很好玩的方法:
到目前为止,所有的效应都会影响到Paint填充图像的方式;PathEffect是用来控制绘制轮廓(线条)的方式。PathEffect对于绘制Path基本图形特别有用,但是它们也可以应用到任何Paint中从而影响线条绘制的方式。使用PathEffect,可以改变一个形状的边角的外观并且控制轮廓的外表。Android包含了多个PathEffect,包括:1)CornerPathEffect 可以使用圆角来代替尖锐的角从而对基本图形的形状尖锐的边角进行平滑。
2)DashPathEffect 可以使用DashPathEffect来创建一个虚线的轮廓(短横线/小圆点),而不是使用实线。你还可以指定任意的虚/实线段的重复模式。
3) DiscretePathEffect 与DashPathEffect相似,但是添加了随机性。当绘制它的时候,需要指定每一段的长度和与原始路径的偏离度。
4)PathDashPathEffect 这种效果可以定义一个新的形状(路径)并将其用作原始路径的轮廓标记。下面的效果可以在一个Paint中组合使用多个Path Effect。1)SumPathEffect 顺序地在一条路径中添加两种效果,这样每一种效果都可以应用到原始路径中,而且两种结果可以结合起来。2)ComposePathEffect 将两种效果组合起来应用,先使用第一种效果,然后在这种效果的基础上应用第二种效果。对象形状的PathEffect的改变会影响到形状的区域。这就能够保证应用到相同形状的填充效果将会绘制到新的边界中。使用setPathEffect方法可以把PathEffect应用到Paint对象中,如下所示:
1 paint.setPathEffect(new CornerPathEffect(10));

其他效果懒得测试了,这个在模拟器上跑的时候效果也不明显,但是真机上跑的时候的确圆滑了许多,看上去很舒服
方法七:
1 //设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果2 setXfermode(Xfermode xfermode);

橡皮擦,这是个好方法啊,看看。
可以通过修改Paint的Xfermode来影响在Canvas已有的图像上面绘制新的颜色的方式。在正常的情况下,在已有的图像上绘图将会在其上面添加一层新的形状。如果新的Paint是完全不透明的,那么它将完全遮挡住下面的Paint;如果它是部分透明的,那么它将会被染上下面的颜色。下面的Xfermode子类可以改变这种行为:1)AvoidXfermode 指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。2)PixelXorXfermode 当覆盖已有的颜色时,应用一个简单的像素XOR操作。3)PorterDuffXfermode 这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。要应用转换模式,可以使用setXferMode方法,如下所示:
1 AvoidXfermode avoid = new AvoidXfermode(Color.BLUE, 10, AvoidXfermode.Mode. AVOID); 2 borderPen.setXfermode(avoid);

这里可以实现完美的橡皮擦功能!代码异常简单:
1 Xfermode xFermode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);2 paint.setXfermode(xFermode);

这是使用的最后一个子类,关于16条Porter-Duff规则,如下:


复制代码

1 private static final Xfermode[] sModes = { 2 new PorterDuffXfermode(PorterDuff.Mode.CLEAR), 3 new PorterDuffXfermode(PorterDuff.Mode.SRC), 4 new PorterDuffXfermode(PorterDuff.Mode.DST), 5 new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER), 6 new PorterDuffXfermode(PorterDuff.Mode.DST_OVER), 7 new PorterDuffXfermode(PorterDuff.Mode.SRC_IN), 8 new PorterDuffXfermode(PorterDuff.Mode.DST_IN), 9 new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT),10 new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),11 new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP),12 new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP),13 new PorterDuffXfermode(PorterDuff.Mode.XOR),14 new PorterDuffXfermode(PorterDuff.Mode.DARKEN),15 new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN),16 new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),17 new PorterDuffXfermode(PorterDuff.Mode.SCREEN)18 };


复制代码

它们每个显示的效果具体如下:



第一个就是Clear效果!
上面很多的图都是由SDK APIDemos运行所得~~有时间仔细研究一下Graphics中的每个Activity。

Java代码
收藏代码

/**
* Paint类介绍
*
* Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了颜色,
* 样式等绘制信息,指定了如何绘制文本和图形,画笔对象有很多设置方法,
* 大体上可以分为两类,一类与图形绘制相关,一类与文本绘制相关。
*
* 1.图形绘制
* setARGB(int a,int r,int g,int b);
* 设置绘制的颜色,a代表透明度,r,g,b代表颜色值。
*
* setAlpha(int a);
* 设置绘制图形的透明度。
*
* setColor(int color);
* 设置绘制的颜色,使用颜色值来表示,该颜色值包括透明度和RGB颜色。
*
* setAntiAlias(boolean aa);
* 设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。
*
* setDither(boolean dither);
* 设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
*
* setFilterBitmap(boolean filter);
* 如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加快显示
* 速度,本设置项依赖于dither和xfermode的设置
*
* setMaskFilter(MaskFilter maskfilter);
* 设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等 *
* setColorFilter(ColorFilter colorfilter);
* 设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果
*
* setPathEffect(PathEffect effect);
* 设置绘制路径的效果,如点画线等
*
* setShader(Shader shader);
* 设置图像效果,使用Shader可以绘制出各种渐变效果
*
* 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);
* 设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果
*
* 2.文本绘制
* setFakeBoldText(boolean fakeBoldText);
* 模拟实现粗体文字,设置在小字体上效果会非常差
*
* setSubpixelText(boolean subpixelText);
* 设置该项为true,将有助于文本在LCD屏幕上的显示效果
*
* 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);
  • 设置带有删除线的效果
 */  

Java代码
收藏代码

private class MyView2 extends View {

    public MyView2(Context context) {  

        super(context);  

    }  

    @Override  
    protected void onDraw(Canvas canvas)  

    {  

        super.onDraw(canvas);  

        canvas.drawColor(Color.WHITE);  

        Paint paint = new Paint();  

        paint.setAntiAlias(true);  

        paint.setColor(Color.RED);  

        paint.setStyle(Paint.Style.STROKE);//设置为空心  

        paint.setStrokeWidth(3);  

        canvas.drawCircle(40, 40, 30, paint);  

        canvas.drawRect(10, 90, 70, 150, paint);  

        canvas.drawRect(10, 170, 70, 200, paint);  

        canvas.drawOval(new RectF(10, 220, 70, 250), paint);  

        Path path = new Path();//三角形  

        path.moveTo(10, 330);  

        path.lineTo(70, 330);  

        path.lineTo(40, 270);  

        path.close();  

        canvas.drawPath(path, paint);  

        Path path1 = new Path();//梯形  

        path1.moveTo(10, 410);//绘画基点  

        path1.lineTo(70, 410);  

        path1.lineTo(55, 350);  

        path1.lineTo(25, 350);  

        path1.close();//把开始的点和最后的点连接在一起,构成一个封闭图形  
        /* 
         * 最重要的就是movtTo和close,如果是Style.FILL的话,不设置close,也没有区别,可是如果是STROKE模式, 
         * 如果不设置close,图形不封闭。 
         *  
         * 当然,你也可以不设置close,再添加一条线,效果一样。 
         */  
        canvas.drawPath(path1, paint);  
          
          
          
          
        ///////////////////////////////////////第二列  

        paint.setColor(Color.BLUE);  

        paint.setStyle(Paint.Style.FILL);//设置实心  

        canvas.drawCircle(120, 40, 30, paint);  

        canvas.drawRect(90, 90, 150, 150, paint);  

        canvas.drawRect(90, 170, 150, 200, paint);  

        RectF re2 = new RectF(90, 220, 150, 250);  

        canvas.drawOval(re2, paint);  

        Path path2 = new Path();  

        path2.moveTo(90, 330);  

        path2.lineTo(150, 330);  

        path2.lineTo(120, 270);  

        path2.close();  

        canvas.drawPath(path2, paint);  

        Path path3 = new Path();  

        path3.moveTo(90, 410);  

        path3.lineTo(150, 410);  

        path3.lineTo(135, 350);  

        path3.lineTo(105, 350);  

        path3.close();  

        canvas.drawPath(path3, paint);  
          
          
        ////////////////////////////////////////////////////第三列  
          
        /* 
         * LinearGradient shader = new LinearGradient(0, 0, endX, endY, new 
         * int[]{startColor, midleColor, endColor},new float[]{0 , 0.5f, 
         * 1.0f}, TileMode.MIRROR); 
         * 参数一为渐变起初点坐标x位置,参数二为y轴位置,参数三和四分辨对应渐变终点 
         * 其中参数new int[]{startColor, midleColor,endColor}是参与渐变效果的颜色集合,  
         * 其中参数new float[]{0 , 0.5f, 1.0f}是定义每个颜色处于的渐变相对位置, 这个参数可以为null,如果为null表示所有的颜色按顺序均匀的分布 
         */  
        Shader mShader = new LinearGradient(0, 0, 100, 100,  

        new int[] { Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW },  

        null, Shader.TileMode.REPEAT);  

        // Shader.TileMode三种模式  

        // REPEAT:沿着渐变方向循环重复  

        // CLAMP:如果在预先定义的范围外画的话,就重复边界的颜色  

        // MIRROR:与REPEAT一样都是循环重复,但这个会对称重复  

        paint.setShader(mShader);// 用Shader中定义定义的颜色来话  

        canvas.drawCircle(200, 40, 30, paint);  

        canvas.drawRect(170, 90, 230, 150, paint);  

        canvas.drawRect(170, 170, 230, 200, paint);  

        RectF re3 = new RectF(170, 220, 230, 250);  

        canvas.drawOval(re3, paint);  

        Path path4 = new Path();  

        path4.moveTo(170, 330);  

        path4.lineTo(230, 330);  

        path4.lineTo(200, 270);  

        path4.close();  

        canvas.drawPath(path4, paint);  

        Path path5 = new Path();  

        path5.moveTo(170, 410);  

        path5.lineTo(230, 410);  

        path5.lineTo(215, 350);  

        path5.lineTo(185, 350);  

        path5.close();  

        canvas.drawPath(path5, paint);  
          
        //////////////////////////////////第4列  

        paint.setTextSize(24);  

        canvas.drawText("圆形", 240, 50, paint);  

        canvas.drawText("正方形", 240, 120, paint);  

        canvas.drawText("长方形", 240, 190, paint);  

        canvas.drawText("椭圆形", 240, 250, paint);  

        canvas.drawText("三角形", 240, 320, paint);  

        canvas.drawText("梯形", 240, 390, paint);  

    }  

}  
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容