资源描述
ANDROID课程讲义-图形图像处理 View类开发框架q在View类框架中,任何自定义的View类都只需要重写onDraw( )方法来进行界面的显示qonDraw( )方法不能被直接调用,想要重新加载界面通常有两种方法,一种是在Handler中调用invalidate,另一种是直接在线程中调用postInvalidate( )qinvalidate( )不能直接在工作者线程中进行调用,因为它违背了单线程模型,而android的UI操作并不是线程安全的。而postInvalidate()可以在工作者线程中直接进行调用图形图像开发基础 图形图像开发基础 SurfaceView类开发框架qsurfaceView继承自View类,它通过一个新线程来更新画面。因此,SurfaceView更适合需要快速加载UI,或渲染代码阻塞UI线程的时间过长的情形qSurfaceView封装了一个Surface对象,而不是Canvas,这一点对于那些资源敏感的操作特别有用qSurfaceView一般通过使用SurfaceHolder类来控制Canvas在其surface上的操作,SurfaceHolder类可以通过getHolder( )来获得 图形图像处理基础 SurfaceView类开发框架 SurfaceHolder中的几个重要的方法lockCanvas( )方法用于锁定画布,这样Surface中就可以指定画布了,之后就可以在画布上进行绘画unlockCanvasAndPost(Canvas canvas):用于释放处于锁定状态的Canvas当Surface的状态发生改变时,可以通过SurfaceHolder.Callback来获取这些信息 SurfaceHolder.Callback有三个重要的方法,surfaceChanged( )、surfaceCreated( )、surfaceDestroyed( )分别在Surface创建、改变、销毁时被调用 GRAPHICS类开发 Paint和Color类q画笔Paint类包含如何绘制几何形状、文本和位图的样式及颜色信息qPaint文本绘制主要包括这些方面,如setColor( )、setTypeface( )、setTextSize( )等qPaint图形图像绘制主要通过setColor( )、setStyle( )等方法来设置 GRAPHICS类开发 Paint和Color类q颜色被表示为封装的数值,这个数值由四个字节组成,分别为alpha、red、green、blue,任何透明性只存储在alpha部分。qColor类定义了一些方法来创建和转换颜色值。如red( int color)、green(int color)、blue(int color)等方法可以获取一个颜色常量值的红绿蓝分色,而HSVToColor( )、RGBToHSV( )等方法可以在不同颜色空间进行颜色的转换。 GRAPHICS类开发 Canvas类介绍要实现一个吸引人的游戏,色彩艳丽的界面设计是必不可少的,这就需要Paint和Canvas配合实现设置Canvas属性的常用方法drawColor( ):用来设置画布背景色,体现在手机上就是手机屏幕背景色clipRect( ):设置裁剪区域,即设置显示区域 rotate( ):旋转画布 GRAPHICS类开发 Canvas类介绍 Canvas常用的绘制方法drawRect(Rect rect, Paint paint)用于绘制矩形区域drawBitmap(bitmap bitmap, Rect src, Rect dst, Paint paint)用于绘制位图drawPoint(float x, float y, Paint paint)用于画点drawLine(float startX, float startY, float stopX, float stopY, Paint paint)用于画线 drawText(String text, float x, float y, Paint paint)用于在某个位置写文本 GRAPHICS类开发 绘制图像 Android中显示图像主要有两步,第一步是获取图像资源,第二步调用画布类的drawBitmap方法进行图像显示。以SurfacView为框架在屏幕中央显示一幅图像如图示 GRAPHICS类开发 图像旋转和缩放 android中对图像的变换操作有平移、旋转、缩放和倾斜四种,android内的Matrix提供了这四种操作方法 Matrix在使用前必须通过reset( )或set( )被初始化。其中对应每种操作都有三种接口setXXX, preXXX,postXXX,在调用这些操作时都可以指定操作中心 setXXX将使当前操作覆盖以前的操作,preXXX和postXXX都是顺序叠加操作,区别在于preXXX是将新变换矩阵左乘原来的操作矩阵,而postXXX是将新变换矩阵右乘原来的操作矩阵 GRAPHICS类开发 图像旋转和缩放图像旋转和缩放效果如图示 GRAPHICS类开发 图像像素操作对图像像素进行操作主要包括两个过程,第一步首先从图像中获取像素值,第二步对像素值进行处理并保存 android中提供了两套操作方法,这些方法都属于Bitmap类,第一套方法针对单像素进行操作,getPixel( )和setPixel( ),第二套为针对批量像素进行操作, getPixels( )和setPixels( ) GRAPHICS类开发 图像像素操作针对单像素的方法将彩色图像变换为黑白图像显示出来效果如图示 GRAPHICS类开发 Shader类介绍 Shader类来对图形图像进行渲染 Shader类包含了子类BitmapShader、LinearGradient、RadialGradient、SweepGradient以及ComposeShader BitmapShader主要用于渲染图像,比如使图像显示在某种特定形状边界内 LinearGradient用来进行线性梯度渲染,比如使绘制的几何图形产生一种线性过渡的色彩 RadialGradient用于进行环形渲染,比如使圆产生环形颜色过渡 SweepGradient是扫描渐变,即围绕一个中心点进行扫描渐变,类似于雷达扫描的效果 ComposeShader是组合渲染,可以组合上面所述的任意两种渲染效果 GRAPHICS类开发 双缓冲技术在游戏开发中,当一幅动画在显示的同时,假如程序又会修改它,这样前面的画面还没有显示完,程序又要求重新绘制,屏幕就会不停闪烁,为了避免闪烁,就必须使用双缓冲技术双缓冲原理是将要处理的图片先在内存中处理完后,再将其显示到屏幕上,这样显示出来的就是一幅完整的图像,不会出现闪烁的现象 android里实现就是在内存中创建一个与原图大小相同的模拟画布,先将要处理的图像画在模拟画布上,当全部处理结束后,再将整幅图显示在真正的画布上 GRAPHICS类开发 设置全屏和获取屏幕属性全屏显示,就是将手机上面的电池、信号显示所处的状态栏以及显示程序名称的标题栏隐藏起来 requestWindowsFeature(Window.FEATURE_NO_TITLE)可以实现隐藏标题栏 getWindows.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN)实现了状态栏的隐藏 GRAPHICS类开发 设置全屏和获取屏幕属性 android通过DisplayMetrics类的getWindowManager().getDefaultDisplay().getMetrics()方法来获取分辨率,用法如下DisplayMetrics dm = new DisplayMetrics() getWindowManager().getDefaultDisplay().getMetrics(dm) 动画实现 Frame动画 Frame动画是最常见的一种实现方法,android逐帧动画通过android.graphics.drawable.AnimationDrawable类来实现,在该类中保存了帧序列以及显示的时间 android提供了一种通过XML来创建逐帧动画的方式,动画创建所用的XML文件的语法格式如下: XML文件通过animation-list来指定这是个AnimationDrawable动画定义,里面的item来指定每帧图片资源路径,duration代表当前帧显示的时间,oneshot为true表示动画只播放一次停止在最后一帧上,如果设置为false表示动画循环播放。下面一个例子通过View显示一个帧动画 动画实现 Tween动画 Tween动画,即通过对场景里面的对象不断做图像变换(平移、缩放、旋转)来产生动画效果,由此可见,实现Tween动画只需要简单的一幅图像就可以了,因此对资源的占用是很少的可以以XML文件方式或者源代码方式预先为Tween定义一组指令,这些指令指定了图形变换的类型、触发时间、持续时间等,程序沿着时间线执行这些指令就可以实现动画效果动画的进度使用Interpolator控制,android提供了几个Interpolator子类 LinearInterpolator类可以实现匀速效果Accelerateinterpolator类可以实现加速效果DecelerateInterpolator类可以实现减速效果 动画实现 Tween动画 Tween动画的两种运行模式独占模式,即程序主线程进入一个循环,根据动画指令不断刷新屏幕,直到动画结束中断模式,即有单独一个线程对时间计数,每隔一定的时间向主线程发通知,主线程接到通知后更新屏幕动画播放过程中对图形的变换通过仿射矩阵实现,简单来说就是,每种变换都是一次矩阵运算在android中,Canvas类中包含当前矩阵,当调用Canvas.drawBitmap(bmp, x, y, Paint)进行绘制时,android会先对bmp做一次矩阵运算,然后将运算结果显示在Canvas上 通过不断修改Canvas的矩阵并刷新屏幕,View内的图形就会不停的做变换,动画就形成了 动画实现 Tween动画 Tween动画的核心模块-Animation类及其子类它实现了各种动画效果,如平移、缩放、旋转、改变透明度等 Tween动画的每一帧都根据Interpolator对图形进行一次变换 Animation是基类,包含了动画的通用属性和方法。主要的属性包括动画持续时间、重复次数、interpolator等动画里最重要的方法是getTransformation( ),该方法根据当前时间和interpolator,计算当前的变换并返回之 TranslateAnimation、RotateAnimation、AlphaAnimation等是Animation的子类,分别实现了平移、旋转、渐变等变换 动画实现 Tween动画 Animation类及其子类继承关系图 动画实现 Tween动画 Tween动画Animation类及其子类每个Animation子类都重载了父类的applyTransformation方法,这个方法会被父类的getTransformation方法调用不同的变换具有不同的属性,如RotateAnimation的属性是起始角度、终止角度和旋转点坐标,TranslateAnimation的属性是起始位置和终止位置,而AlphaAnimation的属性是起始alpha值和终止alpha值 动画实现 Tween动画 Interpolator类及其子类继承关系图 动画实现 Tween动画 Tween动画Interpolator类及其子类 Interpolator类及其子类Interpolator定义了动画的变化速度,可以实现匀速、正加速、负加速、无规则变加速等getInterpolation( )方法用于差值出一个时间线上的点,用于计算图形变换矩阵 LinearInerpolator、AccelerateInterpolator, DecelerateInterpolator,AccelerateDecelerateInterpolator,CycleInterpolator 是 Interpolator的子类,分别实现了匀速、加速、减速、变速、循环等效果 LinearInterpolator,变化率是常数,即f(x)=x对于AccelerateDecelerateInterpolator,变化率开始和结束都很慢,但中间很快,即f(x)=(cos(x+1)*PI)/2.0f)+0.5f 动画实现 Tween动画 Tween动画Transformation类 Transformation类记录了仿射矩阵,动画每触发一次,会对原来的矩阵做一次运算,图形的Bitmap与这个矩阵相乘就可以实现相应的操作(旋转、平移、缩放等) Transformation类有两个重要的成员,一个是mMatrix,另一个是mAlpha 动画实现 Tween动画 View中实现Tween动画创建动画对象,这里是打开一幅图像,调用startAnimation( )启动动画,在此例中当按上、下、左、右键时分别启动渐变、伸缩、平移和旋转动画 startAnimation( )中调用了invalidate( ),从而触发onDraw函数 onDraw函数中的执行过程 调用动画的getTransformation方法,获取根据当前时间和Interpolator计算的矩阵将该矩阵设置为Canvas的当前矩阵调用Canvas的drawBitmap方法绘制屏幕判断getTransformation的返回值,若为true,则调用invalidate方法,刷新屏幕进入下一帧,否则说明动画播放结束 动画实现 Tween动画 Tween动画XML文件进行控制实现在res下新建子目录anim,然后在该子目录下创建两个XML文件如下 动画实现 Tween动画自定义Animation子类Android内提供的动画接口毕竟有限,如果想实现特殊的动画效果,则需要自定义Animation子类自定义子类只需要继承基类并实现applyTransformation( )方法即可 动画实现 gif动画播放由于差值生成各种中间变换的原因,通过Tween生成的动画有时候在播放时并不流畅,而gif动画的播放效果却可以与flash的效果相媲美,如果在自己的游戏中添加一个gif动画,则可以使自己的游戏程序更加吸引用户 Android中提供了一个类:android.graphics.Movie可以用于播放gif,它的使用比较简单使用openRawResource( )方法将gif资源打开,获得输入流 调用Movie的decodeStream( )方法对输入流进行解码在onDraw函数中根据当前时间确定应该播放的帧。另外,在onDraw最后要调用invalidate(),否则只播放第一帧基于Movie对某些gif进行播放时可能会出现花屏现象,如果对播放效果要求较高,则需要自己实现gif解码程序
展开阅读全文