Presentation is loading. Please wait.

Presentation is loading. Please wait.

第9章 Android图形图像处理 QQ号: QQ群: (Android编程-清华版)

Similar presentations


Presentation on theme: "第9章 Android图形图像处理 QQ号: QQ群: (Android编程-清华版)"— Presentation transcript:

1 第9章 Android图形图像处理 QQ号:1281147324 QQ群:489059718(Android编程-清华版)
(公共版) 网络资源:

2 本章知识结构图

3 简单图片 逐帧动画

4 作为一款注重用户体验的应用程序,当然离不开图形、图像的支持。在Android中对图形、图像提供了多种支持,一般使用Bitmap和BitmapFactory方法来封装和管理位图,通过Animation和AnimationDrawable类来保存和控制逐帧动画,使用Canvas和Path两个类绘制各种各样的图形,其中,Canvas可以绘制一些常见的规则图形,而Path则用于绘制一些不规则、自定义的图形。 静态图片即图片内容不发生变化的图片,通常用于显示、增添界面美观,例如图标、背景等。对于这种类型的图片通常由一些图片控件进行处理,如ImageView等。 动态图片即内容、大小、位置等会随着时间而变化的图片,一般采用不断重新绘制的方式来处理,每隔多少毫秒绘制一次,给人的感觉就是连续变化的。

5 2D绘图接口结构

6 9.1 简单图片和逐帧动画 图片不仅可以使用ImageView等图片控件显示,也可以作为Button、TextView等控件的背景。从广义的角度来看,Android应用中图片不仅包括*.png(首选)、*.jpg、*.gif(不建议)等格式的位图,也包括使用XML资源文件定义的各种Drawable对象。 逐帧动画是一种常见的动画形式,其原理是利用人的视觉的滞后性,在时间轴的每帧上绘制不同的内容,然后在足够短的时间内进行播放,给人的感觉就如同连续的动画。 由于逐帧动画的帧序列内容不一样,这不但给制作增加了负担而且最终输出的文件量也很大,但它的优势也很明显:逐帧动画适合于表演细腻的动作。例如:人物走路、说话,动物奔跑等

7 9.1 简单图片和逐帧动画 简单图片 逐帧动画

8 9.1 简单图片和逐帧动画 程序结构

9 简单图片 1.Drawable对象 在Android中操作图片是通过Drawable类来完成的,Drawable类有很多子类,如BitmapDrawable类用于操作位图,AnimationDrawable类用于操作逐帧动画,ShapeDrawable类用于操作形状。 Android不允许图片资源的文件名中出现大写字母,且不能以数字开头。 需要指出的是,R.drawable.Xxx只是一个int类型的常量,代表该Drawable对象的ID,如果在Java程序中需要获得实际的Drawable对象,则可以调用getResources () 方法再调用Resources的getDrawable(int ID)方法来获取。

10 9.1.1 简单图片 2. Bitmap和BitmapFactory
简单图片 2. Bitmap和BitmapFactory Bitmap用于表示一张位图,BitmapDrawable用于封装一个Bitmap对象。 如果想将Bitmap对象包装成BitmapDrawable对象,可以调用BitmapDrawable的构造方法。 BitmapDrawable bd=new BitmapDrawable(Bitmap bitmap); 如果需要获取BitmapDrawable包装的Bitmap对象,可以调用BitmapDrawable的getBitmap()方法。 Bitmap bitmap=bd.getBitmap();

11 简单图片 Bitmap类常用方法 方法 描述 createBitmap (Bitmap source, int x, int y, int width, int height) 从原位图source的指定坐标点 (x,y) 开始,截取宽为width,长为height的部分,创建一个新的Bitmap对象 createBitmap (int width, int height, Bitmap.Config config) 创建一个宽为width,长为height的新位图 getHeight() 获取位图的高度 getWidth() 获取位图的宽度 isRecycle() 返回该Bitmap对象是否已被回收 recycle() 强制一个Bitmap对象立即回收自己

12 9.1.1 简单图片 BitmapFactory类常用方法 方法 描述
简单图片 BitmapFactory是一个工具类,该类所有的方法都是静态方法,这些方法可以从不同的数据源来解析、创建Bitmap对象,如资源ID、路径、文件和数据流等方式。 BitmapFactory类常用方法 方法 描述 decodeByteArray (byte[] data, int offset, int length) 从指定的data字节数组的offset位置,将长度为length的字节数据解析成Bitmap对象 decodeFile (String pathName) 从pathName指定的文件中解析,创建一个Bitmap对象 decodeResource (Resources res, int ID) 从指定的资源ID中解析创建Bitmap对象 decodeStream (InputStream is) 从指定的输入流解析,创建一个Bitmap对象

13 9.1.1 简单图片 3. 实现示例 1 <ImageView 2 android:id="@+id/bitmap1" 3
简单图片 3. 实现示例 1 <ImageView 2 3 android:layout_width="match_parent" 4 android:layout_height="240dp" →高度固定,宽度填充整个屏幕 5 android:scaleType="fitXY" /> →设置图片的缩放方式 6 7 8 android:layout_width="100dp" 9 android:layout_height="100dp" 10 android:layout_gravity="center_horizontal" →高度、宽度固定,位置水平居中 11 android:layout_marginTop="10dp" /> →设置两个ImageView的上下间距

14 简单图片 1 final ImageView bitmap1=(ImageView)findViewById(R.id.bitmap1); →获取ImageView对象 2 final ImageView bitmap2=(ImageView)findViewById(R.id.bitmap2); 3 bitmap1.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.grass)); →获取草地背景的位图 4 bitmap1.setOnTouchListener(new OnTouchListener() { →设置触摸监听器 5 public boolean onTouch(View v, MotionEvent event) { 6 BitmapDrawable bitmapDrawable =(BitmapDrawable)bitmap1.getDrawable(); 7 Bitmap bitmap=bitmapDrawable.getBitmap(); 8 float xchange=bitmap.getWidth()/(float)bitmap1.getWidth(); →获取原图的缩放量 9 float ychange=bitmap.getHeight()/(float)bitmap1.getHeight(); 10 int x=(int)(event.getX()*xchange); →获取触摸的坐标对应原图上的位置 11 int y=(int)(event.getY()*ychange); 12 if(x+50>bitmap.getWidth()){x=bitmap.getWidth()-50;} →对越界情况的处理 13 if(x-50<0){ x=50;} 14 if(y+50>bitmap.getHeight()){y=bitmap.getHeight()-50;} 15 if(y-50<0){ y=50;} 16 bitmap2.setImageBitmap(Bitmap.createBitmap(bitmap, x-50, y-50, 100, 100)); →以点击的位置为中心查看原图的局部细节 17 bitmap2.setVisibility(View.VISIBLE); 18 return false; 19 } 20 });

15 逐帧动画 1.创建逐帧动画 创建逐帧动画的一般方法:先在程序中存放逐帧动画的素材,再在res文件夹下创建一个anim文件夹,再在该文件夹下创建一个XML文档,在<animation-list…/>元素中添加<item…/>元素来定义动画的全部帧。 <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android=" android:oneshot=["true"|"false"]> <item android:drawable="…" android:duration="…"/> </animation-list> 注意:Android也支持在代码中创建逐帧动画,调用AnimationDrawable的addFrame(Drawable frame,int duration) 方法即可,类似于使用XML方法创建时的<item…/>。

16 逐帧动画 其中: (1)android:oneshot属性定义动画是否循环播放。true---只播一次,不循环播放;false---循环播放。 (2)<item.../>元素定义每一张图片的内容和播放持续时间。android:drawable指定内容,android:duration指定时间。 (3)<item...>元素出现的顺序指定图片播放的顺序。 Android也支持在代码中创建逐帧动画: 调用AnimationDrawable的addFrame (Drawable frame, int duration) 方法即可,类似于使用XML方法创建时的<item.../>。

17 逐帧动画 2. 实现示例 程序界面布局中定义了三个组件:两个Button和一个ImageView,两个Button用于控制逐帧动画的开始和停止,ImageView用于显示背景和逐帧动画。

18 9.1.2 逐帧动画 2. 实现示例 布局文件:activity_main.xml <LinearLayout
逐帧动画 布局文件:activity_main.xml 1 <LinearLayout 水平线性布局设置两个按钮 2 android:orientation="horizontal" 3 android:layout_width="match_parent" 4 android:layout_height="wrap_content" 5 android:gravity="center"> 6 <Button “动画开始”按钮 7 8 android:layout_width="wrap_content" 9 10 11 “动画停止”按钮 12 13 14 15 16 </LinearLayout> 17 <ImageView 18 19 20 21 设置草地为背景图片 22 android:scaleType="center" 设置图片的缩放类型 23 /> 逐帧动画为马的奔跑 2. 实现示例

19 逐帧动画 两个按钮代码所在文件:/Bitmap_AnimationTest/src/com/example/bitmap_animationtest/MainActivity.java 2. 实现示例 1 final Button start=(Button)findViewById(R.id.start); 2 final Button stop=(Button)findViewById(R.id.stop); 3 final ImageView animImg=(ImageView)findViewById(R.id.animImg); 4 final AnimationDrawable anim=(AnimationDrawable)animImg.getDrawable(); 获取逐帧动画的AnimationDrawable对象 5 start.setOnClickListener(new OnClickListener() { 为“动画开始”按钮添加单击事件处理 6 public void onClick(View v) { 7 anim.start(); 开始动画 8 } 9 }); 10 stop.setOnClickListener(new OnClickListener() { 为“动画停止”按钮添加单击事件处理 11 12 anim.stop(); 停止动画 13 14

20 9.1.2 逐帧动画 2. 实现示例 该程序在使用android:src="@anim/horse"引用逐帧动画
逐帧动画 2. 实现示例 将逐帧动画作为背景显示, 在代码中将“final AnimationDrawable anim=(AnimationDrawable)img.getDrawable () ;” 改为“final AnimationDrawable anim=(AnimationDrawable)img. getBackground ();”。

21 9.1.3 示例讲解 要实现示例的在简单图片和逐帧动画界面中进行切换功能,需要利用ToggleButton控件。
示例讲解 要实现示例的在简单图片和逐帧动画界面中进行切换功能,需要利用ToggleButton控件。 首先在界面布局中添加ToggleButton控件。 1 <ToggleButton 2 3 android:layout_width="wrap_content" 4 android:layout_height="wrap_content" 5 android:layout_gravity="center_horizontal" 6 →状态为on时显示的文本为“切换到逐帧动画” 7 →状态为off时显示的文本为“切换到简单图片” 8 android:checked="true" /> →设置初始状态为on

22 9.1.3 示例讲解 该示例完整的代码请参考 codes\chapter09\Bitmap_AnimationTest
示例讲解 然后在代码中为ToggleButton添加一个状态改变的监听器,状态为on时显示简单图片的界面,状态为off时显示逐帧动画的界面。 该示例完整的代码请参考 codes\chapter09\Bitmap_AnimationTest

23 9.2 自定义绘图 除了可以使用程序中的图片资源外,Android应用还可以自行绘制图形,也可以在运行时动态地生成图片,前面我们所讲的自定义控件就用到了自定义绘图。 在Android应用中,Canvas和Paint是两个绘图的基本类,使用这两个类几乎可以完成所有的绘制工作。 Canvas:画布,2D图形系统最核心的一个类,作为参数传入onDraw()方法,完成绘制工作,该类提供了各种绘制方法,用于绘制不同的图形,例如点、直线、矩形、圆、文本、颜色、位图等。 Paint:画笔,用于设置绘制的样式、颜色等信息。

24 9.2 自定义绘图 第2章介绍了如何自定义控件 本节介绍利用自定义方法进行绘图的相关类的使用。 示例:自定义绘图的程序。 程序清单:
codes\chapter09\CanvasTest

25 9.2.1 Canvas和Paint Canvas类常用方法 方法 描述
drawArc (RectF oval, float startAngle, float sweepAngle, boolean useCenter, 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) 绘制一条线 drawPoint (float x, float y, Paint paint) 绘制一个点 drawRect (float left, float top, float right, float bottom, Paint paint) 绘制矩形 drawText (String text, float x, float y, Paint paint) 绘制字符串

26 9.2.1 Canvas和Paint Paint类常用方法 方法 描述 setAlpha(int a) 设置透明度
setARGB(int a, int r, int g, int b) 绘制颜色 setColor(int color) 设置颜色 setShader(Shader shader) 设置渲染效果 setShadowLayer(float radius, float dx, float dy, int color) 设置阴影 setStrokeWidth(float width) 设置画笔粗细 setStyle(Paint.Style style) 设置画笔风格

27 9.2.1 Canvas和Paint Paint类常用方法 方法 描述 setAlpha(int a) 设置透明度
setARGB(int a, int r, int g, int b) 绘制颜色 setColor(int color) 设置颜色 setShader(Shader shader) 设置渲染效果 setShadowLayer(float radius, float dx, float dy, int color) 设置阴影 setStrokeWidth(float width) 设置画笔粗细 setStyle(Paint.Style style) 设置画笔风格

28 9.2.2 Shader Shader类的子类 子类 构造方法 描述 BitmapShader
BitmapShader(Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY) 使用位图平铺的渲染效果 LinearGradient LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[ ] positions, Shader.TileMode tile) LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile) 使用线性渐变来渲染图形 RadialGradient RadialGradient (float x, float y, float radius, int[] colors, float[] positions, Shader.TileMode tile) RadialGradient(float x, float y, float radius, int color0, int color1, Shader.TileMode tile) 使用圆形渐变来渲染图形 SweepGradient SweepGradient(float cx, float cy, int[] colors, float[] positions) SweepGradient(float cx, float cy, int color0, int color1) 使用角度渐变来渲染图形 ComposeShader ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode) ComposeShader(Shader shaderA, Shader shaderB, Xfermode mode) 使用组合效果来渲染图形

29 9.2.3 Path和PathEffect Path类常用方法 方法 描述
addCircle(float x, float y, float radius, Path.Direction dir) 为路径添加一个圆形轮廓 addRect(float left, float top, float right, float bottom, Path.Direction dir) 为路径添加一个矩形轮廓 close() 将目前的轮廓闭合,即连接起点和终点 lineTo(float x, float y) 从最后一个点到点(x,y)之间画一条线 moveTo(float x, float y) 设置下一个轮廓的起点

30 PathEffect类的子类 子类 构造方法 描述 CornerPathEffect
CornerPathEffect(float radius) 使用圆角来代替尖角,从而对图形尖锐的边角进行平滑处理 DashPathEffect DashPathEffect(float[] intervals, float phase) 创建一个虚线的轮廓(短横线/小圆点) DiscretePathEffect DiscretePathEffect(float segmentLength, float deviation) 与DashPathEffect相似,但是添加了随机性,需要指定每一段的长度和与原始路径的偏离度 PathDashPathEffect PathDashPathEffect(Path shape, float advance, float phase, PathDashPathEffect. Style style) 定义一个新的路径,并将其用作原始路径的轮廓标记 SumPathEffect SumPathEffect(PathEffect first, PathEffect second) 添加两种效果,将两种效果结合起来 ComposePathEffect ComposePathEffect(PathEffect outerpe, PathEffect innerpe) 在路径上先使用第一种效果,再在此基础上应用第二种效果

31 9.2.4 示例讲解 示例没有采用XML进行界面布局,而是直接使用代码布局 该示例完整的代码请参考
示例讲解 示例没有采用XML进行界面布局,而是直接使用代码布局 该示例完整的代码请参考 codes\chapter09\CanvasTest

32


Download ppt "第9章 Android图形图像处理 QQ号: QQ群: (Android编程-清华版)"

Similar presentations


Ads by Google