本文对Android graphics API 做些整理。

一、颜色 Color类

颜色由一个int型表示,共四个字节。从高位到低位四个字节分别为透明度、红色、绿色、蓝色。
相关API:

1.给定颜色获取相关属性

int alpha(int color)//返回给定颜色的透明度值,也就是高位第一个字节。
int red(int color)  //返回给定颜色的红色色值
int green(int color)
int blue(int color)

2.色调、饱和度、亮度。(下面三个返回值均为 0.0f~1.0f)

float hue(int color)//色调
float saturation(int color)//饱和度
float brightness(int color)//亮度

3.组成颜色

int rgb(int red, int green, int blue) //返回不透明的rgb
int argb(int alpha, int red, int green, int blue)
int parseColor(String colorString)//解析颜色,支持"#xxx...",预定义的几个字符串如"red"、"blue"等

4.颜色转化(hsb: hue色调,saturation饱和度,brghtness亮度
转换后alpha为0xff)

int HSBtoColor(float[] hsb)
int HSBtoColor(float h, float s, float b)
void RGBToHSV(int red, int green, int blue, float hsv[])
void colorToHSV(int color, float hsv[])
int HSVToColor(int alpha, float hsv[]) 

二、画笔 Paint类

参考文章:
Android Paint和Color类
反锯齿办法
android paint cap join 理解 图示

//设置颜色
void setColor(int color);
//抗锯齿
void setAntiAlias(boolean aa);
//设定是否使用图像抖动处理
//会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
void setDither(boolean dither);
//如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作
//加快显示速度,本设置项依赖于dither和xfermode的设置
void setFilterBitmap(boolean filter)
//当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度
void setStrokeWidth(float width);
//这个需要关闭硬件加速才有效果,这个是根据Alpha通道来计算的。
setMaskFilter(MaskFilter maskfilter)
//在图形下面设置阴影层,产生阴影效果radius为阴影的角度
//dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色
setShadowLayer(float radius ,float dx,float dy,int color); 
//画笔的空心与实心,比如画一个圆圈,如果画笔为空心的
//则画出来是空心圆,如果画笔是实心的,画出来是一个实心圆。
void setStyle(Style style);

paint.setStyle(Paint.Style.STROKE);//画笔为空心的

paint.setStyle(Paint.Style.FILL); //画笔为实心的


//当画笔样式为STROKE或FILL_OR_STROKE时,用来控制我们的画笔在离开
//画板时候留下的最后一点图形,竖线处即为画笔结束处
void setStrokeCap(Cap cap);

BUTT
ROUND
SQUARE


paint.setStrokeJoin(Paint.Join.ROUND)

MITER
ROUND
BEVEL


setARGB(int a, int r, int g, int b);//设置画笔颜色
paint.setARGB(128,255,0,0);
canvas.drawCircle(centerX,centerY,200,paint);
paint.setARGB(255,255,0,0);
canvas.drawCircle(centerX+100,centerY,200,paint);


setcolorFilter 

参考
自定义控件其实很简单1/6
Paint、Canvas、Matrix使用讲解(一、Paint)

1.ColorMatrix
它定义了一个 4*5 的float[]类型的矩阵,矩阵中每一行表示 RGBA 中的一个参数。
颜色矩阵M是以一维数组m=[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t]的方式进行存储的;
颜色矩阵:
5x4 matrix for transforming the color+alpha components of a Bitmap. The matrix is stored in a single array, and its treated as follows: [ a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t ] When applied to a color [r, g, b, a], the resulting color is computed as (after clamping)
R’ = a*R + b*G + c*B + d*A + e;
G’ = f*R + g*G + h*B + i*A + j;
B’ = k*R + l*G + m*B + n*A + o;
A’ = p*R + q*G + r*B + s*A + t;

2.LightingColorFilter
LightingColorFilter(int mul, int add)//色彩倍增与偏移,这两个值都是16进制的色彩值0xAARRGGBB。最终颜色的计算方式为:(MUL_COLOR * 原色值 + ADD_COLOR )% 255

3.PorterDuffColorFilter
参考文章:
Porter-Duff 的由来

PorterDuffColorFilter(int color, PorterDuff.Mode mode)

其实就是用一个色值和要绘制的色值进行叠加,然后可以选择叠加的模式(PorterDuff.Mode),PorterDuff.Mode 以枚举的形式定义。
下面的表格中,S:源颜色,D:目标颜色,a:透明度。上面的构造函数参数color,对应下表中的 S,而下表中的D对应画笔要画上去的画布中的像素点的颜色。

PorterDuff的规则不仅用于图像的色彩混合,也用于图形混合。如果用于图像的色彩混合,个人理解,因为是在一个像素点的矩形区域进行,Src和Dst均为大小一样的矩形,像下图中的各种裁剪效果要么变成透明要么色彩叠加,裁剪效果是看不到的。

注意,这张图给人的第一感觉就是两个图形之间的集合之间的交集、并集等的处理,实际上完全不是这么一回事!
要根据上面表格中的计算公式来!

//PorterDuffXfermode  非常强大的图像混合器
//参考上面的PorterDuff.Mode,注意不要用图形集合的方式去理解它
//网上一堆例子抄来抄去,容易误导人,完全不对!按上面的计算公式来!
setXfermode(Xfermode xfermode)

setPathEffect

参考文章 自定义控件其实很简单1/4

setShader

参考文章 Paint的setShader(Shader shader)


文本绘制

//模拟实现粗体文字,设置在小字体上效果会非常差
setFakeBoldText(boolean fakeBoldText);
//设置该项为true,将有助于文本在LCD屏幕上的显示效果
setSubpixelText(boolean subpixelText);
//设置绘制文字的对齐方向
setTextAlign(Paint.Align align);
//设置绘制文字x轴的缩放比例,可以实现文字的拉伸的效果
setTextScaleX(float scaleX);
//设置绘制文字的字号大小
setTextSize(float textSize);
//设置斜体文字,skewX为倾斜弧度
setTextSkewX(float skewX);
//设置Typeface对象,即字体风格,包括粗体,斜体以及衬线体,非衬线体等
setTypeface(Typeface typeface);
//设置带有下划线的文字效果
setUnderlineText(boolean underlineText);
//设置带有删除线的效果
setStrikeThruText(boolean strikeThruText);

三、画布 Canvas类

1.Rect、RectF
Rect 用left、top、right、bottom代表一个矩形区域。
RectF,也就是用 float类型表示的Rect区域。

2.画点

void drawPoints(float[] pts, int offset, int count, Paint paint)
void drawPoints(float[] pts, Paint paint)
void drawPoint(float x, float y, Paint paint);

3.画线

void drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
void drawLines(float[] pts, int offset, int count, Paint paint);
void drawLines(float[] pts, Paint paint) 

4.画矩形

void drawRect(RectF rect, Paint paint)
void drawRect(Rect r, Paint paint)
void drawRect(float left, float top, float right, float bottom, Paint paint)

5.画圆角矩形

drawRoundRect(RectF rect, float rx, float ry, Paint paint) 

6.画圆

void drawCircle(float cx, float cy, float radius, Paint paint) 

7.画椭圆

drawOval(RectF oval, Paint paint);//根据矩形区域的宽高画椭圆

8.画弧

void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,Paint paint)

宽高比为1:2的矩形区域画的圆弧,第四个参数代表是否使用中心点

9.画颜色

drawColor(int color)//把画布用颜色填满
drawColor(int color, PorterDuff.Mode mode)

10.画路径

void drawPath(Path path, Paint paint) 

Path类,代表一路径,支持直线、二阶贝塞尔曲线、三阶贝塞尔曲线,非常强大。

1.线

void lineTo(float x, float y)
rLineTo(float dx, float dy) 

2.贝塞尔曲线
参考 贝塞尔曲线 总结、 贝塞尔曲线

二阶贝塞尔曲线

quadTo(float x1, float y1, float x2, float y2)
rQuadTo(float dx1, float dy1, float dx2, float dy2)

二阶贝塞尔曲线的用法,比较形象的例子参考 HTML5 canvas quadraticCurveTo() 方法
二次贝塞尔曲线需要两个点。第一个点是用于二次贝塞尔计算中的控制点,第二个点是曲线的结束点。曲线的开始点是当前路径中最后一个点。

原理:由 P0 至 P1 的连续点 Q0,描述一条线段。
由 P1 至 P2 的连续点 Q1,描述一条线段。
由 Q0 至 Q1 的连续点 B(t),描述一条二次贝塞尔曲线。
经验:P1-P0为曲线在P0处的切线。
3.三阶贝塞尔曲线
三阶贝塞尔曲线比二阶贝塞尔曲线多了一个控制点,参考HTML5 canvas bezierCurveTo() 方法

cubicTo(float x1, float y1, float x2, float y2,float x3, float y3)
rCubicTo(float x1, float y1, float x2, float y2,float x3, float y3) 

通用公式:


11.弧形路径

void arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo)//弧形路径
void arcTo(RectF oval, float startAngle, float sweepAngle) 

12.画文字

void drawText(char[] text, int index, int count, float x, float y, Paint paint)
void drawText(String text, float x, float y, Paint paint)
void drawText(String text, int start, int end, float x, float y, Paint paint)
void drawText(CharSequence text, int start, int end, float x, float y, Paint paint)

13.在指定路径上画文字

void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)

14.平移、旋转、缩放、错切

void translate(float dx, float dy)
void rotate(float degrees)
void scale(float sx, float sy);
public final void scale(float sx, float sy, float px, float py) {translate(px, py);    //先平移scale(sx, sy);        //再缩放translate(-px, -py);  //在缩放的基础上平移,不会回到刚开始平移之前那个点!
}

————平移、旋转的例子—————-

int radius = 300;
int textSize = 50;
canvas.translate(centerX,centerY);//平移到中心
canvas.save();
canvas.drawCircle(0, 0, radius, paint);
paint.setTextSize(textSize);
paint.setTextAlign(Paint.Align.CENTER);
canvas.rotate(30);
for(int i = 1;i<=12;i++){canvas.drawText(""+i,0,-radius+textSize,paint);
canvas.drawLine(0,-radius+textSize+10,0,-radius+textSize*2,paint);
canvas.rotate(30);
}
canvas.restore();

————平移、缩放、旋转的例子—————-

int radius = 300;
int textSize = 50;
canvas.translate(centerX,centerY);
canvas.save();
canvas.drawCircle(0, 0, radius, paint);
paint.setTextSize(textSize);
paint.setTextAlign(Paint.Align.CENTER);
canvas.rotate(30);
for(int i = 1;i<=12;i++){canvas.drawText(""+i,0,-radius+textSize,paint);
canvas.drawLine(0,-radius+textSize+10,0,-radius+textSize*2,paint);
canvas.rotate(30);
}
canvas.restore();
canvas.scale(0.5f,0.5f);
canvas.rotate(30);
for(int i = 1;i<=12;i++){canvas.drawText(""+i,0,-radius+textSize,paint);
canvas.drawLine(0,-radius+textSize+10,0,-radius+textSize*2,paint);
canvas.rotate(30);
}

————错切—————-

void skew(float sx, float sy);//理解两个参数sx为在x轴方向的tan值,sy为在y轴方向的tan值,错切后面积不变。

比如原图:

x轴方向错切45°:canvas.skew(1, 0);

y轴方向错切45°:canvas.skew(0, 1);


15.Matrix变换
这个就非常牛逼了,上面提到的什么平移、旋转、缩放、错切,本质上,就是把一个坐标(x0,y0)通过一个矩阵变换为(x1,y1)
而通过Matrix转换上面例子中的平移、缩放、旋转、错切统统不在话下。
比如把一个矩形旋转45°:

matrix.setRotate(45);
canvas.concat(matrix);
canvas.drawRect(rectF1, paint);

Matrix相关数学知识可以参考 Android Matrix理论与应用详解
Android matrix偏移(平移),旋转,缩放,倾斜的原理

Matrix相关的api:

void setTranslate(float dx, float dy)
void setScale(float sx, float sy, float px, float py)
void setScale(float sx, float sy)
void setRotate(float degrees, float px, float py)
void setRotate(float degrees)
void setSinCos(float sinValue, float cosValue, float px, float py)
void setSinCos(float sinValue, float cosValue)
void setSkew(float kx, float ky, float px, float py)
void setSkew(float kx, float ky)
boolean setConcat(Matrix a, Matrix b)

注意,对于translate,scale,rotate,skew,concat均有preXXX和postXXX两种类型,而setXXX会清除掉preXXX和postXXX的设置。preXXX相当于矩阵的左乘法,postXXX相当于矩阵的右乘。

还有许多没列出来,以后继续研究。

16.画布状态的保存与恢复

//保存当前的matrix和clip到栈里
int save()
//同上,但是可以指定保留哪些操作
int save(int saveFlags)
//新建一层入栈,后续的draw操作都在这一层画,出栈的时候会把这一层的
//东西画到前一层的上面。而这一层的区域大小,由RectF指定的bounds确定。
int saveLayer(RectF bounds, Paint paint, int saveFlags)
int saveLayer(float left, float top, float right, float bottom, Paint paint,int saveFlags)
//新建一个带透明度的层,alpha值从0~255。
int saveLayerAlpha(RectF bounds, int alpha, int saveFlags)
int saveLayerAlpha(float left, float top, float right, float bottom, int alpha, int saveFlags)
void restore()
int getSaveCount()
void restoreToCount(int saveCount)

例子:
在矩形区域上新建一个半透明的层,并画一个圆。

canvas.translate(centerX, centerY);//移动到中心
RectF rectF1 = new RectF(0,0,200,200);
canvas.drawRect(rectF1, paint);
canvas.saveLayerAlpha(rectF1, 128, Canvas.ALL_SAVE_FLAG);
Paint paint2 = new Paint();
paint2.setColor(Color.RED);
canvas.drawCircle(0,0,100,paint2);
canvas.restore();

可以看见新建的层中,画的圆形的可视区域被限制在层的矩形区域bounds中了。

17.画布的裁剪
画布的裁剪就是把当前层裁剪出一块区域出来,之后的绘画只能在这块区域里画,区域范围外是不可视的。
比如裁剪一块矩形区域,然后画个圆:

canvas.drawColor(Color.BLACK);
canvas.clipRect(100,100,200,200);
canvas.drawCircle(100,100,100,paint)

可以看见圆形的可视区域被限制在裁剪区了。

裁剪的区域是非常灵活的,支持Path。
例如裁剪两个个三角形区域,然后在里面画个圆,可以看见圆形可视区域被限制在两个三角形的路径里了。

canvas.translate(centerX, centerX);
Path path = new Path();
path.lineTo(100,0);
path.lineTo(50, 100);
path.close();
path.moveTo(50,100);
path.lineTo(100,200);
path.lineTo(0,200);
path.close();
canvas.clipPath(path);
canvas.drawColor(Color.RED);
canvas.drawCircle(50,100,50,paint);

裁剪Region
注意clipRegion与clipRect和clipPath不同,canvas的Matrix对clipRegion没有影响,clipRegion不会对Matrix进行转换。
看下面的例子:

canvas.scale(0.5f, 0.5f);
canvas.save();
canvas.clipRect(new Rect(100,100,200,200));//裁剪区域实际大小为50*50
canvas.drawColor(Color.RED);
canvas.restore();
canvas.drawRect(new Rect(0,0,100,100), paint);//矩形实际大小为50*50
canvas.clipRegion(new Region(new Rect(300,300,400,400)));//裁剪区域实际大小为100*100
canvas.drawColor(Color.BLUE);

Region类
参考
Android 2D Graphics学习(二)、Canvas篇2、Canvas裁剪和Region、RegionIterator

Region类似PS中的选区,可以用矩形或者路径来构成选区。

 //构造方法public Region();//创建一个空的区域public Region(Region region); //拷贝一个region的范围public Region(Rect r);  //创建一个矩形的区域public Region(int left, int top, int right, int bottom); //创建一个矩形的区域/**一系列set方法,这些set方法,和上面构造方法形式差不多*/public void setEmpty() {public boolean set(Region region); public boolean set(Rect r) ;public boolean set(int left, int top, int right, int bottom) ;//往一个Region中添加一个Path只有这种方法,//参数clip代表这个整个Region的区域,在在里面裁剪出path范围的区域public boolean setPath(Path path, Region clip) //用指定的Path和裁剪范围构建一个区域//几个判断方法
public native boolean isEmpty();//判断该区域是否为空
public native boolean isRect(); //是否是一个矩阵
public native boolean isComplex();//是否是多个矩阵组合//一系列的getBound方法,返回一个Region的边界
public Rect getBounds();
public boolean getBounds(Rect r);
public Path getBoundaryPath();
public boolean getBoundaryPath(Path path); /**一系列的判断是否包含某点 和是否相交*/
public native boolean contains(int x, int y);//是否包含某点
public boolean quickContains(Rect r)   //是否包含某矩阵
public native boolean quickContains(int left, int top, int right, int bottom) //是否没有包含某矩阵
&nbsp;public boolean quickReject(Rect r) //是否没和该矩阵相交public native boolean quickReject(int left, int top, int right, int bottom); //是否没和该矩阵相交public native boolean quickReject(Region rgn);  //是否没和该矩阵相交/**几个平移变换的方法*/
public void translate(int dx, int dy)
public native void translate(int dx, int dy, Region dst);
public void scale(float scale) //hide
public native void scale(float scale, Region dst);//hide/**一系列组合的方法*/
public final boolean union(Rect r)
public boolean op(Rect r, Op op) {
public boolean op(int left, int top, int right, int bottom, Op op)
public boolean op(Region region, Op op)
public boolean op(Rect rect, Region region, Op op) 选区有一系列的组合操作,
假设用region1  去组合region2
public enum Op {DIFFERENCE(0), //最终区域为region1 与 region2不同的区域INTERSECT(1), // 最终区域为region1 与 region2相交的区域UNION(2),      //最终区域为region1 与 region2组合一起的区域XOR(3),        //最终区域为region1 与 region2相交之外的区域REVERSE_DIFFERENCE(4), //最终区域为region2 与 region1不同的区域REPLACE(5); //最终区域为为region2的区域}

[Android UI] graphics相关推荐

  1. Android UI(五)云通讯录项目之联系人列表,带侧滑选择,带搜索框

    作者:泥沙砖瓦浆木匠 网站:http://blog.csdn.net/jeffli1993 个人签名:打算起手不凡写出鸿篇巨作的人,往往坚持不了完成第一章节. 交流QQ群:[编程之美 36523458 ...

  2. Android UI之ImageView

    前言 这篇博客聊一聊在Android下ImageView的使用,在此篇博客中,会讲解到ImageView的一些属性的使用,以及ImageView展示图片的放大.缩小.旋转等操作.最后再讲解一下Andr ...

  3. android 仿qq好友动态,Android UI仿QQ好友列表分组悬浮效果

    本文实例为大家分享了Android UI仿QQ好友列表分组悬浮效果的具体代码,供大家参考,具体内容如下 楼主是在平板上測试的.图片略微有点大,大家看看效果就好 接下来贴源代码: PinnedHeade ...

  4. Android UI性能优化

    对于Android的UI性能优化,我一般从5个途径来分析: 1.Debug GPU overdraw; 2.Android CPU Profile: 3.dumpsys gfxinfo: 4.Prof ...

  5. 【Android UI】贝塞尔曲线 ⑦ ( 使用 德卡斯特里奥算法 公式计算的 方法绘制三阶贝塞尔曲线示例 )

    文章目录 一.使用 德卡斯特里奥算法 公式计算的 方法绘制三阶贝塞尔曲线 二.代码示例 贝塞尔曲线参考 : https://github.com/venshine/BezierMaker 一.使用 德 ...

  6. Android UI开发第二十五篇——分享一篇自定义的 Action Bar

    Action Bar是android3.0以后才引入的,主要是替代3.0以前的menu和tittle bar.在3.0之前是不能使用Action Bar功能的.这里引入了自定义的Action Bar, ...

  7. Android UI滑动加载源码

    2019独角兽企业重金招聘Python工程师标准>>> android UI 往右滑动,滑动到最后一页就自动加载数据并显示 如图: Java代码 package cn.anycall ...

  8. android教程 - android ui 介绍,多图详解 “Android UI”设计官方教程

    我们曾经给大家一个<MeeGo移动终端设备开发UI设计基础教程>,同时很多朋友都在寻找Android UI开发的教程,我们从Android的官方开发者博客找了一份幻灯片,介绍了一些Andr ...

  9. android ui秘笈,看图说话 – Android UI 设计秘笈 :Part I

    Android 的官方开发者博客发了一份幻灯片,介绍了一些 Android UI 设计的小贴士,Roger 在这里以看图说话的形式发出来,有兴趣的读者就继续往下翻吧.整个 PPT 共分5个部分,Par ...

最新文章

  1. 古朴西安:乘汽船去机场
  2. BeanShell用法汇总(部分摘抄至网络)
  3. mobilenetv2_unet
  4. Yarn将用TypeScript重写,Flow惨遭亲爹抛弃!
  5. 利用bladex+avue实现下拉数据源展示
  6. java day50【综合案例day02】
  7. 【一分钟论文】IJCAI2019 | Self-attentive Biaffine Dependency Parsing
  8. mysql 复杂类型_MySQL 复杂数据类型之JSON数据
  9. 吉林大学校园网linux客户端,吉林大学校园网认证客户端 v5.2.1 pc版
  10. 【转帖】lcd1602中文资料
  11. C#程序员整理的Unity 3D笔记(十三):Unity 3D基于组件的思想
  12. linux如何设置显示器亮度调节软件,为 Linux 启用色温和亮度调节工具
  13. 阿里云服务器价格表,学会利用价格计算器查询阿里云服务器购买价格
  14. Python 小白学习之:linux 基础和 python 入门
  15. 计算hashCode通用计算公式
  16. Re:从0开始的微服务架构:(二)如何快速体验微服务架构?
  17. 压敏电阻14D471K
  18. 华为最新智能服务器,曝光:华为最新一代FusionServer Pro 2488H V6智能服务器
  19. “金融+科技”内外双赋能 拆解数字化浪潮下的平安打法
  20. DP4054国产锂电池500mA充电管理芯片替代LTC4054/TC4054

热门文章

  1. HashSet和HashMap
  2. 自动抓取QQ好友列表?Windows UIA教你轻松实现
  3. 我可以抱你吗?linux
  4. FTP服务器有时候连接超时的问题
  5. linux让前台程序脱离终端运行
  6. 小程序一:利用Python编写一个简单的图书管理系统
  7. 修改ntoskrnl.exe的方法
  8. web页面中如何唤起打开APP
  9. 微软苏菲rt能装鸿蒙,忘记RT,让微软还你一个不一样的“苏菲3”
  10. 乌衣巷的由来是什么?