Paint类API
下面就一起来学习这些用法:ARGB的颜色选择可以使用这网站
设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。
Android包含了下面几种MaskFilter:
BlurMaskFilter 指定了一个模糊的样式和半径来处理Paint的边缘。EmbossMaskFilter 指定了光源的方向和环境光强度来添加浮雕效果。
[x] 需要注意的是,由于在GPU硬件加速模式下,Paint的setMaskFilter不被GPU支持,所以为了能够正常使用setMaskFilter方法,我们需要将我们要绘制的View使用软件渲染模式
//为了确保画笔的setMaskFilter能供起效,我们需要对MyView禁用掉GPU硬件加速 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){ //View从API Level 11才加入setLayerType方法 //设置myView以软件渲染模式绘图 setLayerType(View.LAYER_TYPE_SOFTWARE, null); }radius: 阴影的模糊半径,如上图所示,其值越大表示图形绘制出来越模糊,其值越小图形越清晰。
Blur style:
类型h效果NORMAL同时绘制图形本身内容+内阴影+外阴影,即正常阴影效果SOLID只绘制外阴影和图形内容本身,不绘制内阴影。OUTER不绘制图形内容以及内阴影,只绘制外阴影,即图形轮廓以内完全不绘制,轮廓线以内完全是空白的。INNER绘制图形内容本身+内阴影,不绘制外阴影。是一个float类型的数组,表示光线的方向,是个向量,包含三个值,分别是x分量、y分量、z分量,这三个值的绝对大小并不重要,因为direction最后在真正被Android使用时会被归一化成一个单位向量,即变成长度为1的向量。direction中的坐标是在所画图形的右手坐标系中定义的,如下图所示:
ambient
表示环境光因子,float类型,取值是0到1,值越接近于0,环境光越暗,值越接近于1,环境光越亮。
specular
表示镜面反射因子,float类型,取值也是0到1。镜面反射就是模拟像镜子一样的高光反射,值越接近于0,镜面反射越强,被光照照射到的地方更容易出现很白很亮的状态,即高光效果。
blurRadius
表示模糊半径,是float类型,其值越大,模糊效果越明显。
可以直接传入
ColorMatrixColorFilterLightingColorFilterPorterDuffColorFilter的对象作为参数
在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(透明度)的向量
这个矩阵不同的位置表示的R、G、B、A值,其范围在0.0F至2.0F之间,1为保持原图的RGB值。每一行的第五列数字表示”偏移值“。
”偏移值“:比如:(255, 253, 251, 247)和纯白(255, 255, 255, 255)之间的偏移值(0, 2, 4, 8)我们称之为白平衡的色彩偏移我们来看看这个矩阵是怎么计算的。其实说白了就是矩阵之间的运算乘积:
这里MyColor的RGBA值我们需要转换为[0,1]。通过这种计算我们可以将我们自己设定的颜色和矩阵的颜色进行叠加,创立一个新的颜色
// 生成色彩矩阵 ColorMatrix colorMatrix = new ColorMatrix(new float[]{ -1, 0, 0, 1, 1, 0, -1, 0, 1, 1, 0, 0, -1, 1, 1, 0, 0, 0, 1, 0, }); mPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.kale); canvas.drawBitmap(bitmap,240,600,mPaint);原图
效果图
mul全称是colorMultiply意为色彩倍增,而add全称是colorAdd意为色彩添加,这两个值都是16进制的色彩值0xAARRGGBB、
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 设置颜色过滤 mPaint.setColorFilter(new LightingColorFilter(0xFFFF00FF, 0x00000000)); Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.kale); canvas.drawBitmap(bitmap,240,600,mPaint); }运行后你会发现绿色确实是没了但是原来偏绿的部分现在居然成了红色,当LightingColorFilter(0xFFFFFFFF,0x00000000)的时候原图是不会有任何改变的,如果我们想增加红色的值,那么LightingColorFilter(0xFFFFFFFF, 0x00XX0000)就好,其中XX取值为00至FF。
效果图
这个构造方法也接受两个值,一个是16进制表示的颜色值这个很好理解,而另一个是PorterDuff内部类Mode中的一个常量值,这个值表示混合模式。那么什么是混合模式呢?混合混合必定是有两种东西混才行,第一种就是我们设置的color值而第二种当然就是我们画布上的元素了!也就是说将画布上的元素和我们设置的color进行混合,产生最终的效果。
PorterDuff.Mode modePorterDuff.Mode为枚举类,一共有16个枚举值:
模式效果PorterDuff.Mode.CLEAR所绘制不会提交到画布上。PorterDuff.Mode.SRC显示上层绘制图片PorterDuff.Mode.DST显示下层绘制图片PorterDuff.Mode.SRC_OVER正常绘制显示,上下层绘制叠盖。PorterDuff.Mode.DST_OVER上下层都显示。下层居上显示。PorterDuff.Mode.SRC_IN取两层绘制交集。显示上层。PorterDuff.Mode.DST_IN取两层绘制交集。显示下层。PorterDuff.Mode.SRC_OUT上层绘制非交集部分。PorterDuff.Mode.DST_OUT下层绘制非交集部分。PorterDuff.Mode.SRC_ATOP下层非交集部分与上层交集部分PorterDuff.Mode.DST_ATOP上层非交集部分与下层交集部分PorterDuff.Mode.XOR异或:去除两图层交集部分PorterDuff.Mode.DARKEN取两图层全部区域,交集部分颜色加深PorterDuff.Mode.LIGHTEN取两图层全部,点亮交集部分颜色PorterDuff.Mode.MULTIPLY取两图层交集部分叠加后颜色PorterDuff.Mode.SCREEN取两图层全部区域,交集部分变为透明色 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 设置颜色过滤 mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.DARKEN)); Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.kale); canvas.drawBitmap(bitmap,240,600,mPaint); }效果图
效果是由它的六个子类实现: - ComposePathEffect - CornerPathEffect - DashPathEffec - DiscretePathEffect - PathDashPathEffect - SumPathEffect
例如
mPaint.setPathEffect(new CornerPathEffect(10));将路径的转角变得圆滑
绘制很多“杂点”的突出来模拟一种类似生锈铁丝的效果
new DiscretePathEffect(3.0F, 5.0F)第一个参指定这些突出的“杂点”的密度,值越小杂点越密集;
第二个参数是“杂点”突出的大小,值越大突出的距离越大反之反之。
和DashPathEffect是类似的,但我们自己定义图形和路径虚线的样式。
shape : 是指填充图形 advance : 每个图形间的间距phase : 绘制时的偏移量style : Style.ROTATE、Style.MORPH和Style.TRANSLATE 类型效果Style.ROTATE线段连接处的图形转换以旋转到与下一段移动方向相一致的角度进行转转Style.MORPH图形会以发生拉伸或压缩等变形的情况与下一段相连接Style.TRANSLATE图形会以位置平移的方式与下一段相连接。 Path path = new Path(); path.addCircle(0, 0, 3, Direction.CCW); PathEffect pathEffect = new PathDashPathEffect(path, 12, phase, PathDashPathEffect.Style.ROTATE);效果图:
ComposePathEffect和SumPathEffect都可以用来组合两种路径效果,就是把两种效果二合一。唯一不同的是组合的方式: - ComposePathEffect会先将路径变成innerpe的效果,再去复合outerpe的路径效果,即:outerpe(innerpe(Path)); - SumPathEffect(PathEffect first, PathEffect second)则会把两种路径效果加起来再作用于路径。
PathEffect pe = new DiscretePathEffect(10, 4); PathEffect pe2 = new CornerPathEffect(4); dwShape[3].getPaint().setPathEffect( new ComposePathEffect(pe2, pe));设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果
模式效果AvoidXfermode指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。PixelXorXfermode当覆盖已有的颜色时,应用一个简单的像素XOR操作。PorterDuffXfermode这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。 AvoidXfermode 1 AvoidXfermode avoid = new AvoidXfermode(Color.BLUE, 10, AvoidXfermode.Mode. AVOID); 2 borderPen.setXfermode(avoid) PixelXorXfermode 1 Xfermode xFermode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR); 2 paint.setXfermode(xFermode); PorterDuffXfermode 模式效果PorterDuff.Mode.CLEAR所绘制不会提交到画布上。PorterDuff.Mode.SRC显示上层绘制图片PorterDuff.Mode.DST显示下层绘制图片PorterDuff.Mode.SRC_OVER正常绘制显示,上下层绘制叠盖。PorterDuff.Mode.DST_OVER上下层都显示。下层居上显示。PorterDuff.Mode.SRC_IN取两层绘制交集。显示上层。PorterDuff.Mode.DST_IN取两层绘制交集。显示下层。PorterDuff.Mode.SRC_OUT上层绘制非交集部分。PorterDuff.Mode.DST_OUT下层绘制非交集部分。PorterDuff.Mode.SRC_ATOP下层非交集部分与上层交集部分PorterDuff.Mode.DST_ATOP上层非交集部分与下层交集部分PorterDuff.Mode.XOR异或:去除两图层交集部分PorterDuff.Mode.DARKEN取两图层全部区域,交集部分颜色加深PorterDuff.Mode.LIGHTEN取两图层全部,点亮交集部分颜色PorterDuff.Mode.MULTIPLY取两图层交集部分叠加后颜色PorterDuff.Mode.SCREEN取两图层全部区域,交集部分变为透明色设置绘制的颜色,a代表透明度,r,g,b代表颜色值。
p.setARGB(175, 216, 216, 216);使用颜色值来表示,该颜色值包括透明度和RGB颜色
mBluePaint.setColor(0xff0000ff);使用Shader可以绘制出渲染图像以及一些几何图形
包括了5个直接子类:
BitmapShader 图像渲染ComposeShader 混合渲染LinearGradient 线性渲染RadialGradient 环形渲染SweepGradien 梯度渲染作用是实现某一区域内颜色的线性渐变效果
x0表示渐变的起始点x坐标y0表示渐变的起始点y坐标x1表示渐变的终点x坐标y1表示渐变的终点y坐标colors表示渐变的颜色数组positions用来指定颜色数组的相对位;tile表示平铺方式通常,参数positions设为null,表示颜色数组以斜坡线的形式均匀分布。
另外一种构造方式:
LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile) - color0表示渐变开始颜色 - color1表示渐变结束颜色
利用LinearGradient实现一个从蓝色线性渐变到红色的圆形图:
new LinearGradient(width / 2, 0, width / 2, height, 0xffffffff, 0x00ffffff,Shader.TileMode.CLAMP);作用是实现渲染效果的叠加,如BitmapShader与LinearGradient的混合渲染效果等
参数shaderA表示某一种渲染效果参数shaderB也表示某一种渲染效果参数mode表示两种渲染效果的叠加模式作用是在某一区域内实现环形的渐变效果
参数x表示环形的圆心x坐标参数y表示环形的圆心y坐标参数radius表示环形的半径参数colors表示环形渐变的颜色数组参数positions用来指定颜色数组的相对位置参数tile表示平铺的方式 new RadialGradient(37.5f, 12.5f, 50f, color, darkColor, Shader.TileMode.CLAMP);梯度渲染,是指在某一中心以x轴正方向逆时针旋转一周而形成的扫描效果的渲染形式。
参数cx表示扫描的中心x坐标;参数cy表示扫描的中心y坐标;参数colors表示梯度渐变的颜色数组;参数positions用来指定颜色数组的相对位置。 new SweepGradient(0.0f, 0.0f, 0xff000000, 0xffffffff);产生阴影效果
第一个参数为模糊半径,越大越模糊第二个参数是阴影离开文字的x横向距离第三个参数是阴影离开文字的Y横向距离第四个参数是阴影颜色 valuePaint.setShadowLayer(0.5f, 0, 0.5f, 0xFFFFFFFF);Paint.Style类型有
类型效果Style.FILL实心Style.FILL_AND_STROKE实心和空心兼有Style.STROKE空心 paint.setStyle(Paint.Style.STROKE);当画笔样式为STROKE或FILL_OR_STROKE时可用
Cap.ROUND 圆形样式Cap.SQUARE 方形样式当画笔样式为STROKE或FILL_OR_STROKE时可用
pt.setStrokeWidth(12.0f);设置在小字体上效果会非常差
设置自像素。如果该项为true,将有助于文本在LCD屏幕上的显示效果
可以实现文字的拉伸的效果
默认值是0,负值行间距会收缩
剪切显示,就是大于maxWidth的时候只截取指定长度的显示
p.breakText(text, true, maxSize - 12, null);提取指定范围内的字符串,保存到widths中
mScalePaint.getTextWidths("...", 0, 1, widths);获取文本绘制的路径,提取到Path中
mHugePaint.getTextPath(text, 0, count, 0, 0, path);得到文本的边界,上下左右,提取到bounds中,可以通过这计算文本的宽和高
mTextPaint.getTextBounds( mLabel, 0, mLabel.length(), mBounds );文本FontMetrics类:
textPaint.getFontMetrics();基准点是baseline - ascent:是baseline之上至字符最高处的距离 - descent:是baseline之下至字符最低处的距离 - leading:是上一行字符的descent到下一行的ascent之间的距离,也就是相邻行间的空白距离 - top:是指的是最高字符到baseline的值,即ascent的最大值 - bottom:是指最低字符到baseline的值,即descent的最大值
ascent() + descent() 可以看成文字的height。
mPaint.measureText(text) 可以看成文字的width。
绘画文字时候的x,y坐标为:
dx = (int) mPaint.measureText(String.valueOf(mDayOfMonth)) / 2; dy = (int) (-mPaint.ascent() + mPaint.descent()) / 2;