图形处理

一、概念

Android应用中的图片不仅包括.png、.jpg、*.gif等各种格式的位图,还包括使用XML资源文件定义的各种Drawable对象。

二、Drawable

给Android应用添加Drawable资源之后,Android SDK会在R清单文件中创建一个索引项:R.drawable.file_name。之后既可以在XML资源文件中通过@drawable/file_name访问这个Drawable对象,还可以在Java代码中通过R.drawable.file_name访问该Drawable对象。

R.drawable.file_name只是一个int类型的常量,代表的是Drawable对象的ID,如果Java程序中需要获取实际的Drawable对象,则需要调用Resources的getDrawable(int id)方法来实现。

三、Bitmap

Bitmap代表一个位图,BitmapDrawable中所封装的图片就是一个Bitmap。

把一个Bitmap对象包装成一个BitmapDrawable对象,可以调用BitmapDrawable的构造器:

//把一个Bitmap对象包装成BitmapDrawable对象
BitmapDrawable  drawable  =  new  BitmapDrawable(bitmap);

获取BitmapDrawable所包含的的Bitmap对象,可以调用BitmapDrawable的getBitmap()方法:

//获取BitmapDrawable所包装的Bitmap对象
Bitmap  bitmap  =  drawable.getBitmap();

Bitmap常用方法:

createBitmap(Bitmap source , int x , int y , int width , int height):从源位图source的指定坐标点(给定x、y)开始,从中“挖取”宽、高的一块出来,创建新的Bitmap对象。
createScaledBitmap(Bitmap src , int dstWidth , int dstHeight , boolean filter):对源位图src进行缩放,缩放成宽为dstWidth、高为dstHeight的新位图。
createBitmap(int width , int height , Bitmap.Config config):创建一个宽width、高height的新位图。
createBitmap(Bitmap source , int x , int y , int width , int height , Matrix m , boolean filter):从源位图source的指定坐标点开始,从中“挖取”宽width、高height的一块出来,创建新的Bitmap对象,并按Matrix指定的规则进行交换。

BitmapFactory是一个工具类,它提供了很多方法用于从不同的数据源来解析、创建Bitmap对象。常用方法如下:

decodeByteArray(byte[] data , int offset , int length):从指定字节数组的offset位置开始,将长度为length的字节数据解析成Bitmap对象。
decodeFile(String pathName):从pathName指定的文件中解析、创建Bitmap对象。
decodeFileDescriptor(FileDescriptor fd):用于从FileDescriptor对应的文件中解析、创建Bitmap对象。
decodeResource(Resources res , int id):用于根据给定的资源ID从指定资源中解析、创建Bitmap对象。
decodeStream(InputStream is):用于从指定输入流中解析、创建Bitmap对象。

Android为Bitmap提供了两个方法来判断它是否已回收,以及强制Bitmap回收自己:

boolean isRecycled():返回该Bitmap对象是否已被回收。
void recycle():强制一个Bitmap对象立即回收自己。

四、绘图

Android的绘图应该继承View组件,并重写它的onDraw(Canvas canvas)方法即可。

1.Canvas

Canvas代表依附于指定View的画布,它提供了如下方法来绘制各种图形:

drawArc(RectF oval,float startAngle,float sweepAngle,boolean useCenter,Paint paint) 绘制弧
drawBitmap(Bitmap bitmap,Rect src, Rect dst,Paint paint)    在指定点绘制从源位图中“挖取”的一块
drawBitmap(Bitmap bitmap,float left,float top,Paint paint)  在指定点绘制位图
drawCircle(float cx,float cy,float radius,Paint paint)  在指定点绘制一个圆
drawLine(float startX,float startY,float stopX,float stopY,Paint paint) 绘制一条直线
drawLines(float[] pts,int offset,int count,Paint paint) 绘制多条直线
drawOval(RectF oval,Paint paint)    绘制椭圆
drawPath(Path path,Paint paint) 沿着指定Path绘制任意形状
drawPoint(float x,float y,Paint paint)  绘制一个点
drawPoints(float[] pts,int offset,int count,Paint paint)    绘制多个点
drawRect(float left,float top,float right,float bottom,Paint paint) 绘制矩形
drawRoundRect(RectF rect,float rx,float ry,Paint paint) 绘制圆角矩形
drawText(String text,int start,int end,Paint paint) 绘制字符串
drawTextOnPath(String text,Path path,float hOffset,float vOffset,Paint paint)   沿着路径绘制字符串
clipRect(float left,float top,float right,float bottom) 剪切一个矩形区域
clipRegion(Region region)   剪切指定区域
rotate(float degrees,float px,float py) 对Canvas执行旋转变换
scale(float sx,float sy,float px,float py)  对Canvas执行缩放变换
skew(float sx,float sy) 对Canvas执行倾斜变换
translate(float dx,float dy)    移动Canvas。向右移动dx距离(负数即向左移动);向下移动dy距离(负数即向上移动)

2.Paint

Paint代表Canvas上的画笔,Paint类主要用于设置绘制风格,包括画笔颜色、画笔笔触粗细、填充风格等。提供如下方法:

setARGB(int a,int r,int g,int b)    设置颜色
setColor(int color) 设置颜色
setAlpha(int a) 设置透明度
setAntiAlias(boolean a) 设置是否抗锯齿
setPathEffect(PathEffect effect)    设置绘制路径时的路径效果
setShader(Shader shader)    设置画笔的填充效果
setShadowLayer(float radius,float dx,float dy,int color)    设置阴影
setStrokeWidth(float width) 设置画笔的笔触宽度
setStrokeJoin(Paint.Join join)  设置画笔转弯处的连接风格
setStyle(Paint.Style style) 设置Paint的填充风格
setTextAlign(Paint.Align align) 设置绘制文本时的文字对齐方式
setTextSize(float textSize) 设置绘制文本时的文字大小

3.Path

Path是一个非常有用的类,它可以预先在View上将N个点连成一条“路径”,然后调用Canvas的drawPath(path,paint)方法即可沿着路径绘制图形。

五、图形特效处理

1.使用Matrix控制变换

Matrix是Android提供的一个矩阵工具类,它本身并不能对图形或组件进行变换,但它可以与其他API结合起来控制图形、组件的变换。

使用Matrix控制图形或组件变换的步骤:
1.获取Matrix对象,该Matrix对象既可新创建,也可直接获取其他对象内封装的Matrix;
2.调用Matrix的方法进行平移、旋转、缩放、倾斜等;
3.将程序对Matrix所做的变换应用到指定图形或组件。

Matrix提供了如下方法来控制平移、旋转和缩放:

setTranslate(float dx, float dy):控制Matrix进行平移。
setSkew(float kx, float ky, float px, float py):控制Matrix以px、py为轴心进行倾斜。
setSkew(float kx, float ky):控制Matrix进行倾斜。
setRotate(float degress):控制Matrix进行旋转,degrees控制旋转的角度。
setRotate(float degrees, float px, float py):设置以px、py为轴心进行旋转,degrees为控制旋转的角度。
setScale(float sx, float sy):设置Matrix进行缩放。
setScale(float sx, float sy, float px, float py):设置Matrix以px、py为轴心进行缩放。

Canvas提供了drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)方法,可以在绘制bitmap时应用Matrix上的变换。

2.drawBitmapMesh方法

Canvas提供了一个drawBitmapMesh(Bitmap bitmap, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint)方法,这个方法可以对bitmap进行扭曲。

方法参数说明:
bitmap:指定需要扭曲的源位图。
meshWidth:该参数控制在横向上把该源位图划分成多少格。
meshHeight:该参数控制在纵向上把该源位图划分成多少格。
verts:该参数是一个长度为(meshWidth+1)(meshHeight+1)2的数组,它记录了扭曲后的位图各“顶点”位置。
vertOffset:控制verts数组中从第几个数组元素开始才对bitmap进行扭曲。

3.Shader填充图形

Android不仅可以使用颜色来填充图形,也可以使用Shader对象指定的渲染效果来填充图形。

Shader本身是一个抽象类,它提供了如下实现类:
BitmapShader:使用位图平铺的渲染效果。
LinearGradient:使用线性渐变来填充图形。
RadialGradient:使用圆形渐变来填充图形。
SweepGradient:使用角度渐变来填充图形。
ComposeShader:使用组合渲染效果来填充图形。

六、相关链接

Android Drawable完全解析(二):Drawable子类用法总结(一)

Android绘图之Shader

View之Canvas,Paint,Matrix,RectF等介绍

自定义View进阶篇《十》——Matrix详解

Android:修图技术之瘦脸效果的实现(drawBitmapMesh)

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

推荐阅读更多精彩内容