版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第六章图形与图像处理管理科学工程学院王华杰
ocam@163.com
/basilwang
/basilwang本章要点Android的图形处理基础Bitmap与BitmapFactory继承View实现绘图掌握Canvas、Paint、Path等绘图API双缓冲机制使用Matrix对图像进行几何变换通过drawBitmapMesh方法扭曲图像使用不同的Shader类渲染图形逐帧动画和补间动画SurfaceView本章内容一
使用简单图片二绘图三图形特效处理四逐帧(Frame)动画五补间(Tween)动画六SurfaceView的绘图机制一使用简单图片前面的Android应用中已经大量使用了简单图片,图片不仅可以使用ImageView来显示,也可作为Button、Window的背景。从广义的角度来看,Android应用中的图片不仅包括*.png、*.jpg、*.gif等各种格式的位图,也包括使用XML资源文件定义的各种Drawable对象。一使用简单图片使用Drawable对象
当我们为Android应用增加了Drawable资源以后,AndroidSDK会为这份资源在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(intid)方法来获取。一使用简单图片动手例子:
图片局部放大
对应项目android_04_ImageViewExample
一使用简单图片Bitmap和BitmapFactoryBitmap代表一张位图,BitmapDrawable里封装的图片就是一个Bitmap对象。我们可以把一个Bitmap对象包装成BitmapDrawable对象,可以调用BitmapDrawable的构造器
BitmapDrawabledrawalbe=newBitmapDrawable(bitmap);如果需要获取BitmapDrawable所包装的Bitmap对象,则可调用BitmapDrawable的getBitmap()方法,如下面的代码所示:
Bitmapbitmap=drawable.getBitmap();一使用简单图片Bitmap和BitmapFactory除此之外,Bitmap还提供了一些静态方法来创建新的Bitmap对象,例如如下常用方法。createBitmap(Bitmapsource,intx,inty,intwidth,intheight):从源位图source的指定坐标点(给定x,y)开始,从中截取宽width、高height,创建新的Bitmap对象。createScaledBitmap(Bitmapsrc,intdstWidth,intdstHeight,booleanfilter):对源位图src进行缩放,缩放成宽dstWidth、高dstHeight的新位图。createBitmap(intwidth,intheight,Bitmap.Configconfig):创建一个新位图createBitmap(Bitmapsource,intx,inty,intwidth,intheight,Matrixm,booleanfilter):从源位图source的指定坐标点(给定x,y)开始,从中截取宽width、高height,创建新的Bitmap对象,并按Matrix指定的规则进行变换。一使用简单图片BitmapFactory是一个工具类,它用于提供大量的方法,这些方法可用于从不同的数据源来解析、创建Bitmap对象。BitmapFactory包含了如下方法。decodeByteArray(byte[]data,intoffset,intlength):从指定字节数组的offset位置开始,将长度为length的字节数据解析成Bitmap对象decodeFile(StringpathName):从pathName指定的文件中解析、创建Bitmap对象。decodeFileDescriptor(FileDescriptorfd):用于从FileDescriptor对应的文件中解析、创建Bitmap对象decodeStream(inputStreamis):用于从指定输出流中解析、创建Bitmap对象一使用简单图片大部分时候,我们只要把图片放在/res/drawable目录下,就可以在程序中通过该图片对应的资源ID来获取封装该图片的Drawable对象。但由于手机系统的内存比较小,如果系统不停地去解析、创建Bitmap对象,可能由于前面创建Bitmap所占用的内存还没有回收,而导致程序运行时引发OutOfMemory错误。Android为Bitmap提供了两个方法来判断它是否已回收,以及强制Bitmap回收自己。booleanisRecycled():返回该Bitmap对象是否已被回收voidrecycle():强制一个Bitmap对象立即回收自己一使用简单图片除此之外,如果Android应用需要访问其他存储路径(比如SD卡中)的图片,都需要借助于BitmapFactory来解析、创建Bitmap对象。一使用简单图片动手例子:
查看/assets/目录下图片的查看器
对应项目android_06_ImageAssetsViewExample
二绘图除了使用已有的图片之外,Android应用常需要在运行时动态地生成图片,比如手机游戏的界面。这就需要借助于Android的绘图支持。Android的绘图应该继承View组件,并重写它的onDraw(Canvascanvas)方法即可。重写onDraw(Canvascanvas)方法时涉及一个绘图API:Canvas,Canvas代表了View使用的画布,它提供了以下各种方法绘制图形二绘图方法签名简要说明drawArc(RectFoval,floatstartAngle,floatsweepAngle,booleanuseCenter,Paintpaint)绘制弧drawBitmap(Bitmapbitmap,Rectsrc,Rectdst,Paintpaint)在指定点绘制从源位图中”挖取“的部分drawBitmap(Bitmapbitmap,floatleft,floattop,Paintpaint)在指定点绘制位图drawCircle(floatcx,floatcy,floatradius,Paintpaint)在指定点绘制圆形drawLine(floatstartX,floatstartY,floatstopX,floatstopY,Paintpaint)绘制一条线drawLines(float[]pts,intoffset,intcount,Paintpaint)绘制多条线drawOval(RectFoval,Paintpaint)绘制椭圆drawPath(Pathpath,Paintpaint)沿着指定Path绘制任意形状二绘图方法签名简要说明drawPoint(floatx,floaty,Paintpaint)绘制一个点drawPoints(float[]pts,intoffset,intcount,Paintpaint)绘制多个点drawRect(floatleft,floattop,floatright,floatbottom,Paintpaint)绘制矩形drawRoundRect(RectFrect,floatrx,flostry,Paintpaint)绘制圆角矩形drawText(Stringtext,intstart,intend,Paintpaint)绘制字符串drawTextOnPath(Stringtext,Pathpath,floathOffset,floatvOffset,Paintpaint)沿着路径绘制字符串clipRect(floatleft,floattop,floatright,floatbottom)剪切一个矩形区域clipRegion(Region)剪切指定区域二绘图除了前面定义的各种方法之外,Canvas还提供了如下方法进行变换rotate(floatdegrees,floatpx,floatpy):对Canvas执行旋转scale(floatsx,floatpx,floatpy):对Canvas执行缩放translate(floatdx,floatdy):移动Canvas.向右移动dx距离(dx为负即为向左移动):向下移动dy距离(dy为负即为向上移动)。二绘图Canvas提供的上面的方法还涉及一个API:Paint,Paint代表了Canvas上的画笔,因此Paint类主要用于设置绘制风格,包括画笔颜色、画笔笔触粗细、填充风格等。Paint提供了如下方法二绘图方法签名简要说明setARGB(inta,intr,intg,intb)/setColor(intcolor)设置颜色setAlpha(inta)设置透明度setAntiAlias(booleanaa)设置是否抗锯齿setPathEffect(PathEffecteffect)设置绘制路径时的路径效果setShader(Shadershader)设置画笔的填充效果setShadowLayer(floatradius,floatdx,floatdy,intcolor)设置阴影setStrokeWidth(floatwidht)设置画笔的笔触宽度setStrokeJoin(PaintJointjoin)设置画笔拐弯处的连接风格setStyle(Paint.Stylestyle)设置Paint的填充风格setTextAlign(Paint.Alignalign)设置绘制文本时的文字的对齐方式setTextSize(floattextSize)设置绘制文本时的文字大小二绘图在Canvas提供的绘制方法中还用到一个API:Path,Path代表任意多条直线连接而成的任意图形,当Canvas根据Path绘制时,它可以绘制出任意的形状。二绘画动手例子:
绘制基本的集合图形
对应项目android_06_DrawSomethingExample
关键部分
自定义View组件,程序重写该View组件的onDraw(Canvas)方法
二绘图Path类从前面的程序可以看出,Android提供的Path是一个非常有用的类,它可以预先在View上将N个点连成一条”路径“,然后调用Canvas的drawPath(path,paint)即可沿着路径绘制图形。实际上Android还为路径绘制提供了PathEffect来定义绘制效果,PathEffect包含了如下子类(每个子类代表一种绘制效果):
ComposePathEffectCornerPathEffectDashPathEffectDiscretePathEffectPathDashPathEffectSumPathEffect二绘画动手例子:
*使用不同效果绘制路径
对应项目android_06_DrawPathExample
二绘图除此之外,Android的Canvas还提供了一个drawTextOnPath(Stringtext,Pathpath,floathOffset,floatvOffset,Paintpaint)方法,该方法可以沿着Path绘制文本。其中hOffset参数指定水平偏移、vOffset参数指定垂直偏移。二绘画动手例子:*对应Path路径绘制文本
对应项目android_06_DrawTextOnPathExample
二绘图绘制游戏动画
掌握了Canvas绘画后,如果需要实现游戏动画也是非常简单的。动画其实就是不断地重复调用View组件的onDraw(Canvascanvas)方法,如果每次在View组件上绘制的图形并不相同,就形成动画二绘图绘制游戏动画
为了让View组件上绘制的图形发生改变(无非是位置、大小、角度等发生改变),这就需要程序记住这些状态数据--如果需要游戏动画随用户操作而改变,就为用户动作编写事件监听器,在监听器中修改数据;如果需要游戏动画“自动”改变,就需要使用定时器(Timer),让Timer控制这些状态数据定期修改二绘图绘制游戏动画
不管使用哪种方式,每次View组件上的图形状态数据发生了改变,都应该通知View组件重写调用onDraw(Canvascanvas)方法重绘该组件。通知View重绘可调用invalidate(在UI线程中)或postInvalidate(在非UI线程中)二绘画动手例子:
弹球对应项目android_06_BumpBallExample
二绘画绘制游戏动画本示例要实现一个画图板,当用户在触摸屏上移动时,即可在屏幕上绘制任意的图形动手例子:DrawSomething对应项目android_06_DrawSomethingAnimationExample
二绘画思考:1怎么使用户在触摸屏上自由的画曲线?2每次OnDraw重绘时,原有的内容会丢失,怎么解决?
二绘画思考:1怎么使用户在触摸屏上自由的画曲线?
实际上利用drawLine来画直线,每条直线都是从上一次拖动事件发生点画到本次拖动事件发生点。当用户在触摸屏上移动时,两次拖动事件发生的距离很小,多条极短的直线连起来,看起来就是曲线了。借助于Android提供的Path类,可以非常方便地实现这种效果。2每次OnDraw重绘时,原有的内容会丢失,怎么解决?
当程序需要在指定View上进行绘制时,程序并不直接绘制到该View组件上,而是先绘制到一个内存中的Bitmap图片,等到内存中的Bitmaip绘制好后,在一次性将Bitmap绘制到View组件上
,也就是所谓的“双缓冲”技术三图形特效处理(Matrix)Andoird除了前面介绍的这些图形支持外,还提供了一些额外的图形特效支持,如Matrix三图形特效处理(Matrix)Matrix是Android提供的一个矩阵工具类,它本身并不能对图像或组件进行变换,但它可与其他API结合来控制图形、组件的变换使用Matrix控制图像或组件的步骤如下。1获取Matrix对象,该Matrix对象即可新创建,也可直接获取其他对象内封装的Matrix(例如Transformation对象内部就封装了Matrix)。2调用Matrix的方法进行平移、旋转、缩放、倾斜等3将程序对Matrix所做的变换应用到指定图像或组件三图形特效处理(Matrix)Matrix不仅可用于控制图形的平移、旋转、缩放、倾斜变换,也可以控制View组件进行平移、旋转和缩放等。三图形特效处理(Matrix)Matrix提供了如下方法来控制平移、旋转和缩放setTranslate(floatdx,floatdy):控制Matrix进行平移setRotate(floatdegrees,floatpx,floatpy):设置以px、py为轴心进行旋转,degrees为控制旋转的角度setScale(floatsx,floatsy,floatpx,floatpy):设置Matrix以px、py为轴心进行缩放,sx、sy控制了X、Y方向上的缩放比例setSkew(floatkx,floatky,floatpx,floatpy):控制Matrix以px、py为轴心进行倾斜。kx、ky为x、y方向上的倾斜距离。三图形特效处理(Matrix)一旦对Matrix进行了变换,接下来就可应用该Matrix对图形进行控制了。例如Canvas就提供了一个drawBitmap(Bitmapbitmap,Matrixmatrix,Paintpaint)方法,调用该方法就可以在绘制bitmap时应用Matrix上的变换三图形特效处理(Matrix)动手例子:
键盘控制图形进行Matrix变换(上下键缩放,左右键倾斜)对应项目android_06_KeyboardMatrixExample三图形特效处理(Matrix)动手例子:
飞机”向上“飞行(通过控制背景图片下移)
对应项目android_06_PlaneMoveBackExample四逐帧动画逐帧(Frame)是最容易理解的动画,开发者把动画过程的每张静态图片都收集起来,然后由Android来控制依次显示这些静态图片,利用人眼“视觉暂留”的原理,给用户造成“动画”的错觉。逐帧动画的动画原理与放电影的原理完全一样。四AnimationDrawable与逐帧动画定义逐帧动画非常简单,只要在<animation-list.../>元素中使用<item.../>子元素定义动画的全部帧,并指定各帧的持续时间即可。定义逐帧动画的语法格式如下:<?xmlversion="1.0"encoding="utf-8"?><animation-listxmlns:android=/apk/res/androidandroid:oneshot=["true"|"false"]><itemandroid:drawable="@[package:]drawable/drawable_resource_name"android:duration="integer"/></animation-list>四AnimationDrawable与逐帧动画上面的语法格式中android:onshot控制该动画是否循环播放,如果该参数指定为true,则动画将不会循环播放;否则该动画将会循环播放。每个<item.../>子元素添加一帧。四AnimationDrawable与逐帧动画Android完全支持在Java代码中创建逐帧动画,如果开发者喜欢,开发者完全可以先创建AnimationDrawable对象,然后调用addFrame(Drawableframe,intduration)向该动画中添加帧,每调用一次addFrame方法,就向<animation-list.../>元素中添加一个<item.../>子元素。四AnimationDrawable与逐帧动画一旦程序获取了AnimationDrawable对象之后,接下来就可用ImageView把AnimationDrawable显示出来---习惯上把AnimationDrawable设成ImageView的背景即可。四AnimationDrawable与逐帧动画动手例子:
控制动画的播放和停止对应项目android_06_FrameAnimationExample关键代码(res\anim\fat_po.xml)<animation-listxmlns:android="/apk/res/android"android:oneshot="false"><itemandroid:drawable="@drawable/fat_po_f01"android:duration="60"/><itemandroid:drawable="@drawable/fat_po_f02"android:duration="60"/></animation-list>四AnimationDrawable与逐帧动画需要指出的是,AnimationDrawable代表的动画默认是不播放的,必须在程序中启动动画播放才可以。AnimationDrawable提供了如下两个方法来开始、停止动画。start():开始播放动画。stop():停止播放动画。四AnimationDrawable与逐帧动画动手例子:
在指定点爆炸对应项目android_06_BlastFrameAnimationExample四AnimationDrawable与逐帧动画前面介绍“雷电”飞机游戏时已经提到,当敌机与用户自己的飞机碰撞、或者自己的飞机发射的子弹与敌机碰撞时,都应该在碰撞点播放“飞机爆炸”的动画。
爆炸效果实际上是一个逐帧动画,开发者需要收集从开始爆炸到爆炸结束的所有静态图片,再将这些图片定义成一个逐帧动画,接着在碰撞点播放该逐帧动画即可。
本示例为了突出此处的“主题”---在指定点爆炸,并未增加飞机控制这些细节,只是简单地检测触摸屏事件,当用户触摸触摸屏时,程序将会在触碰点“爆炸”。五补间(Tween)动画Android除了支持逐帧动画之外,也提供了对补间(Tween)动画的支持,补间动画就是开发者只需要指定动画开始、动画结束“关键帧”,而动画变化的“中间帧”由系统计算、并补齐。五补间(Tween)动画补间动画所定义的开始帧、结束帧其实只是一些简单的变化。比如图形大小的缩放、旋转角度的改变等。Android使用Animation代表抽象的动画类,它包括如下几个子类。AlphaAnimation:透明度改变的动画。创建该动画时要指定动画开始的透明度、结束时的透明度和动画的持续时间。其中透明度可从0变化到1ScaleAnimation:大小缩放的动画。创建该动画时需要指定动画开始时的缩放比(以X、Y轴的缩放参数来表示)、结束时动画的缩放比(以X、Y轴的缩放参数来表示),并指定动画持续时间。由于缩放时以不同点为中心缩放效果并不相同,因此指定缩放动画时还要通过pivotX、privotY来指定缩放中心的坐标五补间(Tween)动画TranslateAnimation:位移变化的动画,创建该动画时只要指定动画开始时的位置(以X、Y坐标来表示)、结束时的位置(以X、Y坐标来表示),并指定动画持续时间即可RotateAnimation:旋转动画,创建该动画时只要指定动画开始时的旋转角度、结束时的旋转角度,并制定动画持续时间即可。由于旋转时以不同点为中心旋转效果并不相同,因此指定旋转动画时还要通过pivotX、pivotY来指定“旋转轴心”的坐标五补间(Tween)动画一旦为补间动画指定了3个必要信息,Android就会根据动画的开始帧、结束帧、动画持续时间计算出需要在中间“补入”多少帧,并计算所有补入帧的图形。当用户浏览补间动画时,他看到的依然是“逐帧动画”
为了控制在动画期间需要动态“补入”多少帧,具体在动画运行的那些时刻补入帧,需要借助于Interpolator。五补间(Tween)动画
Interpolator根据特定算法计算出整个动画所需要动态插入帧的密度和位置,简单地说,Interpolator负责控制动画的变化速度,这就使得基本的动画效果(Alpha、Scale、Translate、Rotate)能以匀速变化、加速、减速、抛物线速度等各种速度变化。Interpolator是一个接口,它定义了搜有Interpolator都需要实现的方法:floatgetInterpolation(floatinput),开发者完全可以通过实现Interpolator来控制动画的变化速度。五补间(Tween)动画
Android为Interpolator提供了如下几个实现类,分别用于实现不同动画变化速度。LinearInterpolator:动画以均匀的速度改变AccelerateInterpolator:在动画开始的地方改变速度较慢,然后开始加速。AccelerateDecelerateInterpolator:在动画开始、结束的地方改变速度较慢,在中间的时候加速CycleInterpolator:动画循环播放特定的次数,变化速度按正弦曲线改变DecelerateInterpolator:在动画开始的地方改变速度较快,然后开始减速。五补间(Tween)动画为了在动画资源文件中指定补间动画所使用的Interpolator,定义补间动画的<set.../>元素支持一个android:interpolator属性,该属性的属性值可指定为Android默认支持的Interpolator.
例如:@android:anim/linear_interpolator@android:anim/accelerate_interpolator@android:anim/decelerate_interpolator其实上面的写法很有规律,他们就是把系统提供的Interpolator实现类的类名的驼峰写法改为中划线写法即可。五补间(Tween)动画一旦在程序中通过AnimationUtils得到代表补间动画的Animation之后,接下来就可调用View的startAnimation(Animationanim)方法开始对View执行动画了。虽然Android允许在程序中创建Animation对象,但实际上一般都会采用动画资源文件来定义补间动画五补间(Tween)动画一旦在程序中通过AnimationUtils得到代表补间动画的Animation之后,接下来就可调用View的startAnimation(Animationanim)方法开始对View执行动画了。虽然Android允许在程序中创建Animation对象,但实际上一般都会采用动画资源文件来定义补间动画五补间
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 碎石砂砾供应合约
- 水泥购销简单协议
- 施工项目合同协议
- 专利权合法使用声明
- 房屋买卖合同书格式示例
- 租房品质承诺函
- 驾驶证保证承诺书
- 养老照料陪护合同
- 郑州西亚斯学院《大数据可视化技术与应用》2023-2024学年期末试卷
- 房屋租赁补充协议书
- GB/T 44741-2024农产品产地土壤有效态砷的测定方法
- 第03讲 鉴赏诗歌的表达技巧(课件)-2025年高考语文一轮复习讲练测(新教材新高考)
- 2024-2025部编版语文六年级上册口语交际:意见不同怎么办(课件)
- (2024年)院感知识培训内容(完整详细版)x
- 最美老师评选述职报告
- 幼儿园:中班社会《桌子底下的动物园》
- 2023年05月北京科技大学人才招聘(第二批)笔试历年高频考点试题含答案附详解
- 自动升降柱施工方案(1)
- 绿水青山就是金山银山心得体会范文(三篇)
- 新视野大学英语第三版读写教程第二册Unit5
- 胸椎管狭窄症诊疗指南(全文)
评论
0/150
提交评论