免费预览已结束,剩余1页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Android 画图简介Android apk 里面的画图分为2D和3D两种:2D是由Skia 来实现的,也就是我们在框架图上看到的SGL,SGL也会调用部分opengl 的内容来实现简单的3D效果;3D部分是由OpenGL|ES实现的,OpenGL|ES是Opengl的嵌入式版本,我们先了解一下Android apk的几种画图方式,然后再来来看一看这一整套的图形体系是怎么建立的。 首先画图都是针对提供给应用 程序的一块内存填充数据 , 没去研究过一个Activity是否就对应着底层的一个surface,但是应该都是对这块surface内存进行操作。因此说穿了就是我们要么调用2D 的API画图,要么调用3D的API画图,然后将画下来的图保存在这个内存中,最后这个内存里面的内容会被Opengl渲染以后变为可以在屏幕上的像素信 息。 一 、Apk应用主要关心的还是这些API的使用,在Android apk里面画图有2种方式 2D: 1、Simple Graphics in View 就是直接使用Android已经实现的一些画图操作,比如说images,shapes,colors,pre-defined animation等等,这些简单的画图操作实际上是由skia来提供的2D图形操作。使用这些预定义好的操作,我们可以实现诸如贴一张背景图啊,画出简 单地形状阿,实现一些简单的动画之类的操作。这里的简单可以这么理解,就是我们在这里没有一笔一画地构造出一个图形出来,我们只是把我们的Graphic 资源放入View体系中,由系统 来将这些Graphic画出来。举个例子:我们现在在Activity里面绑定一个ImageView,我们可以设置 这 个ImageView的内容是我们的picture,然后我们可以让这个picture整体颜色上来点蓝色调,然后我们还可以为这个ImageView加 入一个预定义动画,这样当系统要显示这个View的时候就会显示我们的picture,并且会有动画,并带有一个蓝色调,我们并没有自己去定义画图操作, 而是将这些内容放入View中,由系统来将这些内容画出来。这种方式只能画静态或者极为简单的2D图画,对于实时性很强的动画,高品质的游戏都是没法实现 的。 2、Canvas 首先我们要明白这个Canvas是一个2D的概念,是在Skia中定义的。也就是说在这个方式下还是说的画2D图形。我们可以把这个Canvas理解成系 统提供给我们的一块内存区域(但实际上它只是一套画图的API,真正的内存是下面的Bitmap),而且它还提供了一整套对这个内存区域进行操作的方法, 所有的这些操作都是画图API。也就是说在这种方式下我们已经能一笔一划或者使用Graphic来画我们所需要的东西了,要画什么要显示什么都由我们自己 控制。这种方式根据环境还分为两种:一种就是使用普通View的canvas画图,还有一种就是使用专门的SurfaceView的canvas来画图。 两种的主要是区别就是可以在SurfaceView中定义一个专门的线程来完成画图工作,应用程序不需要等待View的刷图,提高性能。前面一种适合处理 量比较小,帧率比较小的动画,比如说象棋游戏之类的;而后一种主要用在游戏,高品质动画方面的画图。下面是这两种方式的典型sequence : 2.1、View canvas (1) 定义一个自己的View :class your_view extends View ; (2) 重载View的onDraw方法:protected void onDraw(Canvas canvas) ; (3) 在onDraw方法中定义你自己的画图操作 ; ps: 可以定义自己的Btimap: Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(b); 但是必须将这个Bitmap放入View的canvas中,画的图才能显示出来:public void drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint) ; invalidate()这个函数被调用后,系统会在不久的将来重新调用onDraw()函数,这个时间很短但并不是可预知的,我曾经在onDraw() 中写了一个if语句,利用validate让系统死循环调用onDraw刷两张图,几乎上这两张图是刷在一起的。 2.2、Surface View Canvas (1) 定义一个自己的SurfaceView : class your_surfaceview extends SurfaceView implements SurfaceHolder.Callback() ; (2) 实现SurfaceHolder.Callback的3个方法surfaceCreated() surfaceChanged() surfaceDestroyed() ; (3) 定义自己的专注于画图的线程 : class your_thread extends Thread() ; (4) 重载线程的run()函数 一般在run中定义画图操作,在surfaceCreated中启动这个线程 (5) 画图的过程一般是这样的: SurfaceHolder surfaceHolder = getHolder() ; /取得holder,这个holder主要是对surface操作的适配,用户不具备对surface操作的权限 surfaceHolder.addCallback(this) ; /注册实现好的callback Canvas canvas surfaceHolder.lockCanvas() ; /取得画图的Canvas /*-画图 *- 画图结束*/ surfaceHolder.unlockCanvasAndPost() ; /提交并显示 所有前面3种方式的画图的一些例子在SDK上都有,写得也比较清楚,我这里就不说了,这里写一下我调这些代码过程一些小经验,应该主要涉及的是Activity这方面,应该以后都用得到: 首先是关于Eclipse的 : (1) ctrl shift O 可以自动添加需要的依赖包,这功能挺实用的觉得,还有alt + /是语法补全 ; (2) 代码中右键比较实用的功能有很多,我记得的是F3找类的声明,F4找类的继承关系 ; (3) 断点调试比较方便的,在Eclipse的右上交可以选择阅读代码的方式,还能经如debug模式,我现在用到的两个打log的方式: Log.e(class, value : + classname) ; /检测class是否为空指针 Log.e(this.getClass().getName(), notice message) ; 然后是关于Activity的 : (1) 首先尽量把UI的设计放在XML中实现,而不要放在代码中实现,这样方便设计,修改和移植 ; (2) 所有使用到的component都必须在manifest中声明,不然程序中找不到相应的conponet的时候会报错 ; (3) 一般每一个Activity都对应于一个类,和一个相应的布局文件xml ; (4) 每一个Activity只有使用setContentView()绑定内容后才会显示,而且你才能从这个内容(比如xml中)获取到你需要的元素 ; (5) res/drawable和res/raw中的元素的区别是drawable中的元素像素可能会被系统优化,而raw中的不会被优化 ; (6) 当多个Activity都从res/drawable中获得同一个元素,如果其中一个修改它的属性,所有其他的Activity中这个元素的相应属性都会改变 ; (7) res/anim中保存的是动画相关的xml ; 下面我们总结以下2D画图用到的包 : android.view /画图是在View中进行的 android.view.animation /定义了一些简单的动画效果Tween Animation 和 Frame. Animation android.graphics /定义了画图比较通用的API,比如canvas,paint,bitmap等 android.graphics.drawable /定义了相应的Drawable(可画的东西),比如说BitmapDrawable,PictureDrawable等 android.graphics.drawable.shapes /定义了一些shape 二、了解了2D,我们再来看看3D的画图方式。3D画图SDK上讲得很简单,只是提了一个通用的方式,就是继承一个View,然后在这个View里面获得 Opengl的句柄进行画图,道理应该来说是和2D一样的,差别就是一个是使用2D的API画图,一个是使用3D的。不过因为3D openGl|ES具有一套本身的运行机制,比如渲染的过程控制等,因此Android为我们提供了一个专门的用在3D画图上的 GLSurfaceView。这个类被放在一个单独的包android.opengl里面,其中实现了其他View所不具备的操作: (1) 具有OpenGL|ES调用过程中的错误跟踪,检查工具,这样就方便了Opengl编程过程的debug ; (2) 所有的画图是在一个专门的Surface上进行,这个Surface可以最后被组合到android的View体系中 ; (3) 它可以根据EGL的配置来选择自己的buffer类型,比如RGB565,depth16 (这里有点疑问,SurfaceHolder的类型是SURFACE_TYPE_GPU,内存就是从EGL分配过来的?) (4) 所有画图的操作都通过render来提供,而且render对Opengl的调用是在一个单独的线程中 (5) Opengl的运行周期与Activity的生命周期可以协调 下面我们再看看利用GLSurface画3D图形的一个典型的Sequence (1) 选择你的EGL配置(就是你画图需要的buffer类型) optional : setEGLConfigChooser(boolean) setEGLConfigChooser(EGLConfigChooser) setEGLConfigChooser(int, int, int, int, int, int) (2) 选择是否需要Debug信息 optional : setDebugFlags(int) setGLWrapper(GLSurfaceView.GLWrapper). (3) 为GLSurfaceView注册一个画图的renderer : setRenderer(GLSurfaceView.Renderer) (4) 设置reander mode,可以为持续渲染或者根据命令 来渲染,默认是continuous rendering optional: setRenderMode(int) 这里有一个要注意的地方就是必须将Opengl的运行和Activity的生命周期绑定在一起,也就是说Activity pause的时候,opengl的渲染也必须pause。另外GLSurfaceView还提供了一个非常实用的线程间交互的函数 queueEvent(Runnable),可以用在主线程和render线程之间的交互,下面就是SDK提供的范例: class MyGLSurfaceView extends GLSurfaceView private MyRenderer mMyRenderer; public void start() mMyRenderer = .; setRenderer(mMyRenderer); public boolean onKeyDown(int keyCode, KeyEvent event) if (keyCode = KeyEvent.KEYCODE_DPAD_CENTER) queueEvent(new Runnable() / This method will be called on the rendering / thread: public void run() mMyRenderer.handleDpadCenter(); ); return true; return super.onKeyDown(keyCode, event); GLSurfaceView是Android提供的一个非常值得学习 的类,它实际上是一个如何在View中添加画图线程的例子,如何在Java 中使用线程的例子,如何添加事件队列的例子,一个使用SurfaceView画图的经典Sequence,一个如何定义Debug信息的例子,觉得把它看懂了可以学到很多知识 ,具体的源码在:/framworks/base/opengl/java/android/opengl/GLSurfaceView.java 。 3D的内容基本到这里基本讲完了,剩下的主要是如何使用Opengl API的问题了,可以看看API demo中简单的立方体,复杂的可以看看它那个魔方的实现。下面我们总结一下3D画图需要用到的包: Android.opengl /主要定义了GLSurfaceView javax.microedition.khronos.egl /java层的egl接口 javax.microedition.khronos.opengles /openglAPI 三、了解了2D和3D基本的画图方法,我们再回过头来看看整个Android对Opengl和kia的调用层次关系 3.1、首先来看2D,2D是主要使用的图形引擎,毕竟3D受制于其过高的硬件要求在手机上使用还是比较少,而且Skia也能部分实现类似于3D的效果, 因此可以说SKia实现了Android平台上绝大多数的图形工作。下面我们来看看从应用层到底层对skia的调用关系: Android对skia的调用是一个比较经典 的调用过程,应用程序的几个包是在SDK中提供的;JNI放在框架的JNI目录下面的Graphic目录;skia是作为一个第三方组件放在external目录下面。我们可以稍微了解一下skia的结构: 这里主要涉及到的3个库: libcorecg.so 包含/skia/src/core的部分内容,比如其中的Region,Rect是在SurfaceFlinger里面计算可是区域的操作基本单位 libsgl.so 包含/skia/src/core|effects|images|ports|utils的部分和全部内容,这个实现了skia大部分的图形效果,以及图形格式的编解码 libskiagl.so 包含/skia/src/gl里面的内容,主要用来调用opengl实现部分效果 另外我看到/skia/src中有两个目录animator和view没有写入makefile的编译路径中,我觉得这两个目录是很重要的,不知道是现在Android还没使用到,还是用其他的方式加载进去的。 要想在底层使用skia的接口来画图
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 收获机械制造工操作技能测试考核试卷含答案
- 灌区供水工操作规程测试考核试卷含答案
- 金属轧制工安全培训评优考核试卷含答案
- 2025秋北师大版(2022)小学劳动技术三年级第一学期期末模拟试题及答案
- 函数的单调性与最值(2大考点+6大题型)-2026年新高考数学一轮复习(讲义+专练)解析版
- 解析通识教育
- 广西壮族自治区柳州市2024-2025学年四年级上学期语文11月期中试卷(含答案)
- 揭秘太空科学
- 教育科技创新探索
- 广西部分学校2025-2026学年高一年级上册开学质量检测物理试题(解析版)
- 农用无人机管理制度
- 清欠试题及答案
- 《人应当坚持正义》练习题高二语文(高教版2023拓展模块上册)
- 西藏土地买卖合同范本
- 诈骗案谅解协议书
- 临沂市兰陵县程村农村宅基地地块土壤污染状况调查报告
- 租赁光伏组件合同协议
- 自救互救知识培训课件
- 入团的考试题目及答案
- 2024秋新鲁教版英语六年级上册课件 Unit 5 Section A (Pronunciation 1-2e)(第2课时)
- 幼儿园常用表格-保教工作考核表附-日常工作管理及绩效考核细则
评论
0/150
提交评论