是什么
Paint,顾名思义,就是画,作动词画画,引申为画笔,所以paint就相当于我们平常使用的画笔,而对paint的一些setXXX操作就是日常对画笔粗细,颜色等的操作,但是程序中的paint可能会比生活中的更强大些。
怎么样
API文档解释:
The Paint class holds the style and color information about how to draw geometries, text and bitmaps.
从Api定义可知,画笔持有样式和颜色信息,关于怎么样的信息呢,关于如何绘制几何图形,文本和位图的样式和颜色信息。
大体分为两类,图形绘制和文本绘制。
怎么用
从构造方法开始看

有图可知,Paint有三个构造方法,
- 第一个是无参数构造方法,也是默认构造方法,携带默认设置,比如默认黑色,无坑锯齿,不加粗等。
- 第二个是带flags参数的构造方法,将光标移到这个构造方法上,会对flags做这样的解释
Android学习之Paint图形图像处理(一)
初看以为是flags的枚举,于是在使用时这样
发现没有,原来重点在前一句
set the paint's flags
设置paint的flags,当然是用Paint去获得flags呀~
对着api文档,一一解释这里的枚举类型是什么作用,也可以直接查看API文档
截了一张图,更直观
分别表示:
- 可抗锯齿
- 可设置字间距
- 可抖动
- 可设定标记
- 可过滤位图
- 设置暗示模式为HINTING_OFF,不可暗示
- 设置暗示模式为HINTING_OFF,可暗示
- 设置为线性文本
- 设置为删除线效果文本
- 设置为可亚像素文本
- 设置为下划线效果文本
当在构造方法中设置了这些值,就不用通过paint对象去设置了,但我个人认为,通过对象去设置更为方便
- 第三个是设置Paint参数的构造方法,初始化paint的属性,感觉和第二个构造方法很相似,不知道有啥区别,而且paint都有那么多setXXX方法了为什么还要加这两个个构造方法呢,直接对默认的对象进行设置不行么?这是我的疑问,可能很无知,但我确实不知道,如果有幸被哪位知道的人看到了,麻烦告诉我一声,谢谢~
从API开始看
图形绘制
// 参数1,透明度,参数2:红,参数3:绿,参数4:蓝 均为int 类型,取值范围0~255,不是小数
setARGB(int a,int r,int g,int b);
//设置透明度,参数同上参数1,取值范围相同
setAlpha(int a);
//设置颜色,使用颜色值来表示,该颜色值包括透明度和RGB颜色
setColor(int color);
//设置是否坑锯齿,会消耗大量资源,绘图速度变慢[这个属性要实际理解,在后面借用别人的一张图]
setAntiAlias(boolean b);
//设置是否使用图像抖动处理,设置为true会使绘制出来的图像更加平滑饱满[这个属性要实际理解,在后面借用别人的一张图]
setDither(boolean dither);
//设置是否使用图像抖动处理,如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加快显示速度,但图片效果可能会受影响,本设置项依赖于dither和xfermode的设置[这个属性要实际理解,在后面借用别人的一张图]
setFilterBitmap(boolean filter);
//设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等 ,后面在研究
setMaskFilter(MaskFilter maskfilter);
//设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果,后面研究
setColorFilter(ColorFilter colorfilter);
//设置画笔样式
setStyle(Paint.Style style);
//设置绘制路径的效果,如点画线,线画几何等
setPathEffect(PathEffect effect)
//设置图像效果,使用Shader可以绘制出各种渐变效果[后面的文章再详细复习]
setShader(Shader shader);
//在图形下面设置阴影层,产生阴影效果,radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色
setShadowLayer(float radius ,float dx,float dy,int color);
//当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式,如圆形样式Cap.ROUND,或方形样式Cap.SQUARE,与setStyle结合使用
setStrokeCap(Paint.Cap cap);
//设置绘制时各图形的结合方式,如平滑效果等[后面详细复习]
setSrokeJoin(Paint.Join join);
//设置描边宽度,与setStroke结合使用
setStrokeWidth(float width);
//设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果,参数设置可参照这篇文章[Xfermode ](http://407827531.iteye.com/blog/1470519)
setXfermode(Xfermode xfermode);
文本绘制
//模拟实现粗体文字,如果字体太小会挤成一团,效果不好
setFakeBoldText(boolean fakeBoldText);
//设置设置亚像素文本,该项为true,将有助于文本在LCD屏幕上的显示效果,该设置与第二个构造方法中SUBPIXE_TEXT_FLAG一样
setSubpixelText(boolean subpixelText);
//设置绘制文字的对齐方向
setTextAlign(Paint.Align align);
//设置绘制文字x轴的缩放比例,可以实现文字的拉伸的效果
setTextScaleX(float scaleX);
//设置绘制文本的大小
setTextSize(float textSize);
//设置斜体文字,skewX为倾斜弧度
setTextSkewX(float skewX);
//设置Typeface对象,即字体风格,包括粗体,斜体以及衬线体,非衬线体等
//Typeface.DEFAULT:默认字体。Typeface.DEFAULT_BOLD:加粗字体。Typeface.MONOSPACE:monospace字体。Typeface.SANS_SERIF:sans字体。Typeface.SERIF:serif字体。
setTypeface(Typeface typeface);
设置带有下划线的文字效果
setUnderlineText(boolean underlineText);
//设置带有删除线的效果
setStrikeThruText(boolean strikeThruText);
着重API
- setColor(int color)
在xml里面我们通常使用#加A~F六位或者八位来设置颜色值,带#号的颜色表示方法
其实就是32位argb的表示方案,然而在setColor里面我们需要传入int值,所以需要把#改成0x,比如白色在xml中表示为#ffffff,在java代码中表示为0xffffff。
-
setARGB(int a,int r.int g,int b)
和setColor差不多,也是设置颜色值,但这里是分开设置,同样的每个参数还可以用十六进制的int值来传入,比如绿色 #FF00FF00 就可以传入,setARGB(0xFF,0x00,0xFF,0x00),同理也可以用十进制的来传入,setARGB(255,0,255,0)
-
setStyle(Paint.Style s)
设置画笔的样式, 样式取值 有三种:
Paint.Style.FILL :填充内部
Paint.Style.FILL_AND_STROKE :填充内部和描边
Paint.Style.STROKE :仅描边
-
setStrokeWidth(float w)
设置画笔描边宽度
-
setAntAlias(boolean b)
设置是否坑锯齿,设置抗锯齿会增加资源消耗,使绘制时间增长。
盗用五长老的图加以理解
Android学习之Paint图形图像处理(一) -
setStrokeJoin(Paint.Join j)
设置线段连接处的连接模式,取值有:
Join.MITER(结合处为锐角)
Join.Round(结合处为圆弧)
Join.BEVEL(结合处为直线)
-
setTypeface(Typeface typeface) 字体样式
有五种:
Typeface.DEFAULT:默认字体。
Typeface.DEFAULT_BOLD:加粗字体。
Typeface.MONOSPACE:monospace字体。
Typeface.SANS_SERIF:sans字体。
Typeface.SERIF:serif字体。
-
setDither(boolean dither);
设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
这里我盗用五长老的两张图看看效果
设置为false的情况
Android学习之Paint图形图像处理(一)
设置为true的情况
true比false更柔和。
- setLetterSpacing(float letterSpacing):设置行间距,默认为0
- setLinearText (boolean linearText)
这个引用五长老的解释
设置是否打开线性文本标识,这玩意对大多数人来说都很奇怪不知道这玩意什么意思。想要明白这东西你要先知道文本在Android中是如何进行存储和计算的。在Android中文本的绘制需要使用一个bitmap作为单个字符的缓存,既然是缓存必定要使用一定的空间,我们可以通过setLinearText (true)告诉Android我们不需要这样的文本缓存。
-
setXfermode (Xfermode xfermode)
参考文章http://407827531.iteye.com/blog/1470519
-
setColorFilter(ColorFilter filter)
比较复杂,参照文章http://www.cnblogs.com/tianzhijiexian/p/4297104.html
- reset();画笔重置,将设置归0,设为默认值。
小
Demo
创建项目,新建java类
MyView
继承View,重写构造方法和onDraw方法
package com.cd.paintdemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Xfermode;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by Sky
* on 2016/10/28.
* Describe:
*/
public class MyView extends View {
Paint mPaint;
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//指定画布的背景为白色
canvas.drawColor(Color.WHITE);
//创建采用默认设置的画笔
mPaint=new Paint();
//使用坑锯齿功能
mPaint.setAntiAlias(true);
//设置笔触的宽度
mPaint.setStrokeWidth();
//设置填充样式为描边
mPaint.setStyle(Paint.Style.STROKE);
//绘制蓝色的圆形
mPaint.setColor(Color.BLUE);
canvas.drawCircle(,,,mPaint);
//绘制黄色的圆形
mPaint.setColor(Color.YELLOW);
canvas.drawCircle(,,,mPaint);
//绘制黑色的圆形
mPaint.setColor(Color.BLACK);
canvas.drawCircle(,,,mPaint);
//绘制绿色的圆形
mPaint.setColor(Color.GREEN);
canvas.drawCircle(,,,mPaint);
//绘制红色的圆形
mPaint.setColor(Color.RED);
canvas.drawCircle(,,,mPaint);
}
}
删除xml中默认的textview,使用自定义的这个view
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.cd.paintdemo.MainActivity">
<com.cd.paintdemo.MyView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
运行结果
参考文章:
http://www.jianshu.com/p/7116e1b429c0
http://www.jianshu.com/p/be3785a33582
http://www.jianshu.com/p/f801a4528651
http://www.jianshu.com/p/3edecb48aa68