android之绘图——Canvas,bitmap,Paint的理解
来源:互联网 发布:多乐炸金花作弊软件 编辑:程序博客网 时间:2024/05/16 17:53
经常要和绘图打交道,总是用Canvas,bitmap,Paint,但是对它们的理解总是模糊,这里作下总结,加深对绘图的理解。
查询Canvas的官方解释:Canvas用来实现对绘图的操作。你需要4个组件来实现绘图的操作:
a).bitmap,保存着像素
b).canvas.执行画图的命令(向bitmap执行写操作)
c).drawing primtive(e.g.Rect,Path,text,bitmap).绘图的原始内容。
d).paint.(用来描述绘图时的使用的颜色和风格)
这些解释都很抽象,下面我来说下对它们的形象的理解,说明这4个基本控件,这样加深印象:
我们就用现实中的画图来比拟对android中绘图的理解:
a)bitmap.我们绘图肯定需要一块画布,这个画布承载内容用来表现所要显示的图。它有大小,你可以在上面涂颜料进行绘图,或什么都不涂。
b).canvas.画布本身不会被绘制,只有当画家去操作画笔,画布才会绘制上图画。这里的canvas就像相当于画家执行画图的操作,绘图的过程。
c).drawing primitive.画家绘图需要参照物,比如你绘图,肯定是有个目标,比如绘制一个字体,一个圆圈,一个矩形(Rect),另一幅图(bitmap)。
d).paint.绘图需要画笔,paint就相当于这个画笔,你可以定制颜色,粗细。
下面了解Canvas,bitmap,paint一些常用的方法:
Bitmap
.获取bitmap方法
读取InputStream得到位图
InputStream is = getResources().openRawResource(R.drawable.ic_launcher);BitmapDrawable bd = new BitmapDrawable(is);Bitmap bp = bd.getBitmap();解码位图来获取位图,如果你在解析大图片遇到OOM问题,不妨尝试这个方法,这个方法利用JNI调用来解析bitmap,减轻了java层空间的压力。
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);位图的创建,你可以利用下面方法来创建一个bitmap
matrix 指定对bitmap像素的操作createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter);//width,height用来指定创建图片的大小,config用来指定创建图片的质量,其中config有共有4个标准:ALPHA_8,ARGB_4444,ARGB_8888,RBG_565,这些标准分别定义图片像素存储的情况,RBG_565是比较常用的,ARBG_8888指定的图片质量最高createBitmap(int width, int height, Bitmap.Config config);createBitmap(Bitmap source, int x, int y, int width, int height);
Canvas
Canvas();创建一个空画布,它必须绑定bitmap才有效,一般以bitmap来创建一个bitmap的操作,当canvas进行绘图,他绘制的内容都绘在bitmap上。
常见的Canvas绘制使用场合:
a.自定义View时绘制
@OverrideOnDraw(Canvas canvas){//利用canvas执行绘图操作}
b.利用surfaceView时绘制
SurfaceHoler holder = SurfaceView.getHolder();Canvas canvas = holder.lockCanvas();//利用canvas进行绘图操作holder.unlockCanvasAndPost(canvas);//对canvas解锁,并更新
绘制图形的方法:
drawCircle(float cx, float cy, float radius, Paint paint);//绘制圆圈
drawLine(float startX, float startY, float stopX, float stopY, Paint paint)//绘制直线
裁剪绘图区域
clipXXX()方法类
从当前区域里裁剪一块新的画图区域,裁剪后的新区域即为绘图的新区域。
save(),restore()方法
在绘图时,我们经常会用到canvas类的save(), restore()方法,它们到底是怎么用的呢?
这里有篇详细讲解这两个方法的文章,和大家分享:
https://developer.mozilla.org/en/Canvas_tutorial/Transformations
*save,用来保存Canvas状态,调用之后,你可以调用canvas对画布进行平移、缩放、裁剪等操作。
*restore.用来恢复Canvas之前保存的状态,这样不仅能够复用先前保存的状态,节约资源,另一方面避免对影响图片后续的绘制。
Paint
Paint(),//创建画笔
setColor(int color)//设置画笔的颜色
setAlpha(int a)//设置图片透明度
setDither(boolean dither)//设置画笔是否反锯齿
setStrokeWidth(float width)//设置画笔的宽度
小例子学习
做一小例子温习巩固绘图的操作,要求实现仿卷帘拉起效果。
先简述一下情景:。首先,手机上显示一张完整的图片,图片顶端固定不变。然后,手指在图片上开始滑动,图片的底部随着手指位置而不断变化。你看到的效果是图片的从顶端显示你手指滑动的所在位置。所以,你看到的总是不完整的图片。先上效果,这样大家更好理解。
为了实现上述效果的复用,我们可以自定义一个view,可以设置背景图片,提示的箭头的图片以及图片顶端保留空间大小。
1.自定义MovingView.java,实现上述功能
package com.lawrence;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.PorterDuff;import android.graphics.Rect;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;public class MovingView extends View {private Bitmap backgroundBitmap;private Bitmap handleBitmap;private Bitmap showBitmap;private int backgroundWidth;private int backgroundHeight;private int handleWidth;private int handleHeight;private int currentY;private int showHeight;private int topSpace;private Canvas mCanvas;private Rect backgroundSrc;public MovingView(Context context, AttributeSet attrs) {super(context, attrs);TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Movingview);//获取背景图片Drawable backgroundDrawable = a.getDrawable(R.styleable.Movingview_movingbackground);//获取拉手图片Drawable handleDrawable = a.getDrawable(R.styleable.Movingview_handlebackground);//获取顶端保留的高度大小。这个高度用做滑动到顶部保留的最小高度。topSpace = (int) a.getDimension(R.styleable.Movingview_extraspace, 10);backgroundBitmap = ((BitmapDrawable) backgroundDrawable).getBitmap();handleBitmap = ((BitmapDrawable) handleDrawable).getBitmap();//获取图片高宽backgroundWidth = backgroundBitmap.getWidth();backgroundHeight = backgroundBitmap.getHeight();handleWidth = handleBitmap.getWidth();handleHeight = handleBitmap.getHeight();//根据图片大小创建一个相同大小的bitmapshowBitmap = Bitmap.createBitmap(backgroundWidth, backgroundHeight + (handleHeight >> 1), Config.RGB_565);//创建一个canvas,并绑定bitmap。mCanvas = new Canvas(showBitmap);//绘制定backgroundBitmap到showBitmap。mCanvas.drawBitmap(backgroundBitmap, 0, 0, null);//在backgroundBitmap底部的中间位置绘制拉手图片mCanvas.drawBitmap(handleBitmap, (backgroundWidth - handleWidth) >> 1, backgroundHeight - (handleHeight >> 1), null);}public MovingView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public MovingView(Context context) {super(context);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//设置图片的大小为此View的大小setMeasuredDimension(backgroundWidth, backgroundHeight + (handleHeight >> 1));}@Overrideprotected void onDraw(Canvas canvas) {//更新绘制图片canvas.drawBitmap(showBitmap, 0, 0, null);}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:break;case MotionEvent.ACTION_MOVE:currentY = (int) event.getY();showHeight = currentY;if(showHeight > backgroundHeight)showHeight = backgroundHeight;if(showHeight < topSpace)showHeight = topSpace;//清除图片mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);//根据滑动位置确定新绘制区域backgroundSrc = new Rect(0, 0, backgroundWidth, showHeight);//绘制背景mCanvas.drawBitmap(backgroundBitmap, backgroundSrc, backgroundSrc, null);//绘制拉手mCanvas.drawBitmap(handleBitmap, (backgroundWidth - handleWidth) >> 1, showHeight - (handleHeight >> 1), null);invalidate();//更新break;case MotionEvent.ACTION_UP:break;}return true;}}2.自定义MovingView的属性:
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="Movingview"> <attr name="movingbackground" format="reference"/> <attr name="handlebackground" format="reference"/> <attr name="extraspace" format="dimension"/> </declare-styleable></resources>
3.布局文件main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:moving="http://schemas.android.com/apk/res/com.lawrence" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /><com.lawrence.MovingView android:id="@+id/imageview" android:layout_width="wrap_content" android:layout_height="wrap_content" moving:extraspace="30dp" moving:movingbackground="@drawable/bofucur" moving:handlebackground="@drawable/updownsel" /></LinearLayout>
主Activity就不贴了,很简单,只要setcontentView(R.layout.main).
附:Demo源码位置:http://download.csdn.net/detail/a2758963/4459566
- android之绘图——Canvas,bitmap,Paint的理解
- Canvas,Bitmap,Paint的理解
- Android 高级绘图 Canvas, Paint , Bitmap
- Android绘图-Paint、Canvas、Bitmap、BitmapFactory
- Android绘图总结(Bitmap,Canvas,Paint,圆角)
- Android绘图Canvas、Paint
- Android Canvas,Paint 绘图
- Android:图形图像之使用Canvas,Paint绘图
- Android绘图基础之: Canvas 和 Paint
- Android的Canvas、Bitmap、Drawable和Paint
- Android基础知识(9)—Android绘图基础Canvas、Paint
- Android画图学习总结(一)——Android Drawable、Bitmap、Canvas和Paint的区别
- 自定义view—绘图基础Canvas+Paint
- android 用paint,canvas 绘图
- 通过创建一个位图的XY Chart来学习Android绘图类Rect,Paint,Bitmap,Canvas(附源码)
- 通过创建一个位图的XY Chart来学习Android绘图类Rect,Paint,Bitmap,Canvas(附源码)
- 初学Android,图形图像之使用Canvas,Paint绘图(二十五)
- Android 2D绘图解析之 Canvas,Paint
- Android SDK 提示“a folder failed to be renamed or moved on sdk install 的处理方法”
- 用户空间与kernel空间通信的例子(利用mmap)
- hdu 4313 #回溯
- jdk 1.5 新特性 (ZZ)
- JS跨域访问
- android之绘图——Canvas,bitmap,Paint的理解
- blog/时间设置
- EL表达式
- HDOJ2037
- HK_C_U\Software\Microsoft\Windows\ShellNoRoam\MUICache键值作用
- ADO的Command对象
- win7/xp 双击执行jar包出现:could not find the main class
- 了解驱动程序和操作系统基础
- 嵌入式linux启动信息完全注释