`
mybluesoul1989
  • 浏览: 16430 次
  • 性别: Icon_minigender_1
  • 来自: 成都
最近访客 更多访客>>
社区版块
存档分类
最新评论

Graphics学习篇

阅读更多

从接触JAVA到J2EE,再到J2ME,然后是现在的Android,这条路上我竟然没有真正拥有过其中一样技能,更可怕的是仿佛一切尽是空白。我太不擅长学以致用了。所以,我想还是通过博客/日志的形式,一点一点地记录下自己曾经用心做过,即便没有成功的事情。当然,这也不是我幡然醒悟。因为明白问题所在,与解决问题之间,往往需要很长一段时间。而这段时间对我来说已然太长,足以让我绝望;同时也使我明白效率是一个人能力的很大体现。但愿自己天天向上。

 

以后会陆续在这里写下自己的学习历程(坚持……多看、多想、多做,最重要的是要多作总结,这样既可以方便回顾,又可以加强理解)。

 

在Android Dev Guide里,把Graphics分为两大类:2D Graphics和3D with OpenGL。其中,2D Graphics的大部分APIs都放在drawable包里。3D 则可以在OpenGL ES,还有一些OpenGL工具包里找到。

 

 

1、2D Graphics绘制

 

首先要提到Drawable(android.Graphics.drawable.Drawable),这个类可以通过Resources的方法getDrawable(int id)获得。也就是说,Drawable是可以直接跟资源文件关联的,但是它并不是可视组件,属于底层数据。所以还需要调用draw(Canvas canvas)方法,将数据装载进可描绘的容器中。需要注意的是:切记不要忘了setBound()。(在之前很多次学习中,遇到了令人尴尬的问题:没有对Drawable进行绘制区域界定,即setBounds()。结果是无论怎么改程序,就是不显示。莫非默认区域是“零”?我想,是的。//在后面的DEV GUIDE中看到了关于shapeDrawable的说明:If you do not set the bounds, then the shape will not be drawn, whereas if you don't set the color, it will default to black.我认为这对Drawable来说是一致的,颜色除外。个人觉得不进行绘制与绘制区域为“零”是等价的,不知道在底层是如何判断的。有待考证。。。)

 

既然说到了Canvas(android.Graphics.Canvas),那么我们就来分析下这个类(这个类非比寻常,我认为是相当重头戏的一个类)。Canvas在API里的描述是拥有调用“绘制图像能力”的一个类,这个能力就是draw...(..., Paint),也就是说可对各种图像原型进行描绘,包括基本形状(矩形、圆、路径、文字、点、线等)和Bitmap(这是一个持有像素控制能力的类)。 参数中带有Paint类,这是因为在这个机制中我们还需要提供对“颜色、图像样式等”属性进行解析的服务,而Paint就是这个功能组件。

 

其次要说的是Bitmap(android.Graphics.Bitmap),这个类是通过一系列静态方法获得实例,如:Bitmap myBitmap = Bitmap.createBitmap(int width, int height, Config)。那么它作何用呢?前面提到了Bitmap可以控制像素,那么可以说,它其实是一个像素容器,它与Canvas直接关联,很多时候我们都会用Canvas(Bitmap)这个构造函数去实例化Canvas。对于参数Config有必要进行说明一下,Config是一个常量,我们通常使用Bitmap.Config.ARGB_8888(A指Alpha,即透明通道;RGB分别指Red,Green,Blue,即三原色;后面的8888指代各个通道的颜色位深,也就是常说的32位色彩深度。)。我想这个解释应该会有助于对“像素容器”这个概念的理解吧。

 

最后对Paint(android.Graphics.Paint)稍加说明一下,API里描述如下:Paint持有图像样式和颜色信息(关于如何描绘几何体、文本和位图的信息)。

 

除了以上4个类之外,在2D绘图中,有些时候我们也会使用BitmapFactory这个类。在API中,这个类包含了多个静态方法,实现从files(如Resources)、streams(如InputStream)、Byte-array生成Bitmap对象。在总结中的第二种方法,就是用的BitmapFactory,免去了使用Drawable关联资源文件的麻烦。

 

(1)通用View作为容器的绘图机制

自定义View类(即继承View)的绘图:需要重写onDraw(Canvas),在实例化View子类(包括XML布局文件的调用和构造函数的调用)的过程中,系统会自动调用onDraw(Canvas)进行绘图。在这之后,系统几乎不会再去调用(更准确地说是只在必要的情况下去调用),那么怎么去告诉系统我们需要重绘呢?直接通过对象调用onDraw()是不允许的,于是我们需要invalidate()和postInvalidate()这两个方法,前者用在UI线程中,后者用在非UI线程中。说白了,就是使之前的面板无效,所以系统就自动重绘了。

误解:我们是不是可以把绘图功能写在onDraw(Canvas)之外的方法里,那么我们就可以通过对象进行调用了,重绘效果是一样的?

答案是否定的,这个绘图机制是不允许在onDraw(Canvas)之外重绘的,尝试的结果是空指针异常,但是可以通过onDraw(Canvas)调用外部方法(说白了还是必须在onDraw(Canvas)里实现)。

 

总结绘图机制如下:

方法一:利用Drawable关联资源文件和Canvas。Drawable负责解析资源文件,把数据提交到Canvas,执行绘图操作。

@Override
public void onDraw(Canvas canvas)
{
	super.onDraw(canvas);
	Resources res = getResources();
	Drawable mDrawable = res.getDrawable(R.drawable.background);
	mDrawable.setBounds(0, 0, this.getWidth(), this.getHeight());//这里铺满屏幕。
	mDrawable.draw(canvas);
}

 

  方法二:利用BitmapFactory解析资源文件。

 

问题:关于这个方法,在Bitmap对象生成的过程中,没有上述的Config属性,那么它的像素信息又在哪儿定义呢?难道有默认值?有待考证。不过毕竟人那是BitmapFactory,工厂嘛,批量生产。嘿嘿。

@Override
public void onDraw(Canvas canvas)
{
	super.onDraw(canvas);
	Resources res = getResources();
	Bitmap mBitmap = BitmapFactory.decodeResource(res, R.drawable.earthrise);
	mBitmap = Bitmap.createScaledBitmap(mBitmap, getWidth(), getHeight(), true);//对图片资源进行缩放,这里是全屏覆盖。
	canvas.drawBitmap(mBitmap, 0, 0, new Paint());//这个笔刷可以为null。为啥?有待深入。。。
}

 

(2)使用SurfaceView类作为容器的绘图机制

尽管SurfaceView是View的子类,但是在绘图上却与View大不相同。在这个绘图机制里,系统是不会调用onDraw(Canvas)这个函数的,它采用的是implements SurfaceHolder.Callback的方法。也就是实现SurfaceHolder.Callback这个接口,然后使用SurfaceHolder这个类进行控制。

这个绘图机制的一个优点是很大程度上提高画面重绘的帧率,适合游戏画面描绘。原因是它有独立的缓存(貌似是Surface类),同时还可以通过外部加速(如硬件加速)。

 

总结绘图机制:所用的绘图流程与通用View下的绘图一致,但是并不重写onDraw(Canvas),而是重写SurfaceHolder.Callback接口下的方法(surfaceCreated(...), surfaceChange(...), surfaceDestory(...)//参数参见API),在实例化自定义SurfaceView子类时,首先调用surfaceCreated(...),随即调用surfaceChange(...),在销毁时调用surfaceDestory。

切记:这个绘图机制与之前提及的“通用View绘图“尽管在借助Drawable、Bitmap、BitmapFactory、Canvas和Paint的使用上是一致的,但是底层实现是不同的。并且这个机制下,View.onDraw(Canvas)这个方法是无法被调用的。与View同理,画面绘制只能介于Created与Destory之间(称为有效/合法生命周期),不论直接在这三个重写方法(其实只有前两个,销毁就免了)里实现,还是重写方法调用外部方法都是可行的,但请不要尝试用对象mView.doDraw()类似的途径,会出现空指针异常。原理为何?有待考证。。。

下面给出其中一个方法,另一个可参照“通用View作为容器的绘图机制“:

//这是采用BitmapFactory的方法。

 

@Override
public void surfaceCreated(SurfaceHolder holder) 
{//注意:其实这是实现接口的抽象方法,虽然也是重写方法,但是super(将父类的方法沿用)是没有意义的,因为super本身是抽象的。
	Resources res = getResources();
	Bitmap mBitmap = BitmapFactory.decodeResource(res, R.drawable.earthrise);
	mBitmap = Bitmap.createScaledBitmap(mBitmap, getWidth(), getHeight(), true);
	Canvas canvas = holder.lockCanvas();//锁住,并取回画布
	canvas.drawBitmap(mBitmap, 0, 0, new Paint());
	holder.unlockCanvasAndPost(canvas);//释放,并提交画布
}
 

 

 

待续……

 

分享到:
评论
3 楼 gf_crazy 2011-12-21  
写的很好,帮助很大,似懂非懂的地方看后清晰好多。
2 楼 zhf1zhf2 2011-07-01  
含糊不懂,我这个刚入门的没能明白!
1 楼 sinye 2010-07-14  
写的很精彩,收到很多启发!麻烦问一下,SurfaceView的surfaceCreated()和View的Ondraw方法能达到同一个目的吗?就是说,当在UI线程里调用invalidate()和非UI线程里调用postInvalidate(),他们都会调用各自的绘图方法吗!

相关推荐

    QT学习之路2 (1~82篇)

    30. Graphics View Framework 31. 贪吃蛇游戏(1) 32. 贪吃蛇游戏(2) 33. 贪吃蛇游戏(3) 34. 贪吃蛇游戏(4) 35. 文件 36. 二进制文件读写 37. 文本文件读写 38. 存储容器 39. 遍历容器 40. 隐式数据共享 41. ...

    dojo精品中文教程(包一)

    Dojo学习笔记--dojo.graphics.color & dojo.uri.Uri Dojo学习笔记--dojo.string & dojo.lang Dojo学习笔记--动态生成widget Dojo学习笔记--开发自己的TitlePane Dojo学习笔记--页面部分区域遮挡,DialogUnderlay ...

    dojo精品中文教程(包二)

    Dojo学习笔记--dojo.graphics.color & dojo.uri.Uri Dojo学习笔记--dojo.string & dojo.lang Dojo学习笔记--动态生成widget Dojo学习笔记--开发自己的TitlePane Dojo学习笔记--页面部分区域遮挡,DialogUnderlay ...

    dojo精品中文教程(包三)

    Dojo学习笔记--dojo.graphics.color & dojo.uri.Uri Dojo学习笔记--dojo.string & dojo.lang Dojo学习笔记--动态生成widget Dojo学习笔记--开发自己的TitlePane Dojo学习笔记--页面部分区域遮挡,DialogUnderlay ...

    dojo精品中文教程(全)

    Dojo学习笔记--dojo.graphics.color & dojo.uri.Uri Dojo学习笔记--dojo.string & dojo.lang Dojo学习笔记--动态生成widget Dojo学习笔记--开发自己的TitlePane Dojo学习笔记--页面部分区域遮挡,DialogUnderlay ...

    Asp.Net从零开始22(Graphics画图表)

    没有Asp.net开发经验的朋友可以看看这篇文章,可以从零开始学习各种ASP.NET技能。本资料是本人整理的ASP.NET与C#的基础资料。如需了解请查阅VS.NET的相关书籍。省略的内容有ASP.NET基础语法、C#基础语法、HTML语法、...

    Android代码-GraphicsTestBed

    此项目为学习Android Graphics时写的各种Demo,根据目录排放如下,后面整理好会添加一些滤镜处理和OpenGLES进阶Demo。也欢迎大家有合适的Graphic Demo提交进来,最好带有博客讲解。 Camera CameraV1: 根据Camera第...

    基于python的猜单词游戏开发

    基于python的猜单词游戏,里面有海龟模块的调用,也有graphics做图形界面的例子,可以帮助你们学习游戏开发的基本思路以及部分模块的调用

    opengl Manual

    本书是OpenGL Architecture Review Board, Mason Woo、 Jackie Neider、Tom Davis 和Dave Shreinre编著的《OpenGL编程指南(第3版)》(Reading, MA: Addison-Wesley, 1999)的姊妹篇。阅读这两本书的前提是你...

    ASP.NET3.5从入门到精通

    15.2.1 Graphics 类 15.2.2 绘制基本图形 15.2.3 图形绘制实例 15.3 绘制文字特效 15.3.1 投影特效 15.3.2 倒影特效 15.3.3 旋转特效 15.4 绘制图片 15.4.1 载入图像文件 15.4.2 GDI+输出图像 15.5 图像特效处理 ...

    Java图像处理教程之正片叠底效果的实现

    正片叠底效果是我们平时在Photoshop中会见到的一种效果,下面这篇文章主要给大家介绍了关于利用Java如何实现正片叠底的效果,分享出来供大家参考学习,文中给出了详细的示例代码供大家参考学习,需要的朋友可以参考...

    VC绘图 游戏简易教程

     讲解以简单实用为主,不要指望看了这几篇文章后就能过二级考试。  目标,除了能做小游戏外,更重要的,是锻炼编程思想,以备将来做更大的程序。 学习方式  以自学为主吧,有问题就在相关课程后面跟帖就行,...

    Doing Bayesian Data Analysis: A Tutorial with R and BUGS

    全书分成三部分,第一部分为基础篇:关于参数、概率、贝叶斯法则及R软件,第二部分为二元比例推断的基本理论,第三部分为广义线性模型。内容包括贝叶斯统计的基本理论、实验设计的有关知识、以层次模型和MCMC为代表...

    精通Qt4编程(第二版)源代码

    初 级 篇 \第1章 Qt初步实践 2 \1.1 第一个Qt程序 2 \1.1.1 建立主程序 2 \1.1.2 建立工程 3 \1.1.3 编译/运行第一个Qt应用程序 8 \1.1.4 第一个Qt程序的代码分析 8 \1.2 使用Qt布局管理器 11 \1.3 关联操作...

    精通qt4编程(源代码)

    初 级 篇 \第1章 Qt初步实践 2 \1.1 第一个Qt程序 2 \1.1.1 建立主程序 2 \1.1.2 建立工程 3 \1.1.3 编译/运行第一个Qt应用程序 8 \1.1.4 第一个Qt程序的代码分析 8 \1.2 使用Qt布局管理器 11 \1.3 关联操作 12 \1.4...

    Android openGl 绘制简单图形的实现示例

    学习五部曲,弄清楚5个W一个H(when(什么时候使用)、where(在哪个地方使用?)、who(对谁使用)、what(是个什么东西)、why(为什么要这么用?).一个H即:how(到底该怎么用?)),基本的概念篇主要围绕这几个...

    openGL 参考手册

    本书是OpenGL Architecture Review Board, Mason Woo、 Jackie Neider、Tom Davis 和Dave Shreinre编著的《OpenGL编程指南(第3版)》(Reading, MA: Addison-Wesley, 1999)的姊妹篇。阅读这两本书的前提是你...

    Java2游戏编程.pdf

    7.2 Graphics2D类 7.3 使用仿射变换 7.4 绘制形状 7.5 实例建模 7.6 Image类 7.7 更多的绘制和填充操作 7.7.1 Stroke接口 7.7.2 BasicStroke类 7.7.3 Paint接口 7.7.4 混合处理 7.8 处理文本 7.8.1 创建并画出文本 ...

    ASP.NET 3.5 开发大全word课件

    这是整部学习资料 由于太大第一章免费供应给大家 在我的上传资源中 如果觉得还不过希望大家给个好评 当然具体本书的作者就不深究了把! 第1章 认识ASP.NET 3.5 1.1 什么是ASP.NET 1.1.1 .NET历史与展望 1.1.2 ASP...

    ASP.NET 3.5 开发大全11-15

    15.2.1 Graphics类 15.2.2 绘制基本图形 15.2.3 图形绘制实例 15.3 绘制文字特效 15.3.1 投影特效 15.3.2 倒影特效 15.3.3 旋转特效 15.4 绘制图片 15.4.1 载入图像文件 15.4.2 GDI+输出图像 15.5 图像特效处理 ...

Global site tag (gtag.js) - Google Analytics