zoukankan      html  css  js  c++  java
  • Andriod中绘(画)图----Canvas的使用详解

       转载请注明出处:http://blog.csdn.net/qinjuning    

                由于在网络上找到关于Canvas的使用都比较抽象,也许是我的逻辑思维不太好吧,总是感觉理解起来比较困难,

        尤其是对save()和restore()方法的使用。本篇文章的内容就是对Canvas的使用进行一下总结,包括它的两种不同的使用

        情节和它的一些方法进行一下说明。 

      

           1  Bitmap,可以来自资源/文件,也可以在程序中创建,实际上的功能相当于图片的存储空间;

           2  Canvas,紧密与Bitmap联系,把Bitmap比喻内容的话,那么Canvas就是提供了众多方法操作Bitamp的平台;

           3  Paint,与Canvas紧密联系,是"画板"上的笔刷工具,也用于设置View控件上的样式;

           4  Drawable,如果说前三者是看不见地在内存中画图(虚拟的),那么Drawable就是把前三者绘图结果表现出来的接口(真实的)。

                  Drawable多个子类,例如:位图(BitmapDrawable)、图形(ShapeDrawable)、图层(LayerDrawable)等。

       

          以上引自于hellogv的Android入门第十四篇之画图》

        我们打个简单的比方吧:

                    Paint        就是画笔

                    Bitmap    就是画布

                    Canvas   就是画家

         于是,画家可以通过画笔可以在画布上进行任何的画画。

    Canvas的两种使用情形,从Canvas对象的获得角度分析:

        1、  自定义View和自定义SurfaceView中获得Canvas对象

           由于自定义View和SurfaceView在显示界面中已经获得了显示区域,canvas对象只不过是在其显示(绘画)区域进行界面布局

      的设计,当操作完毕后,系统会显示canvas的操作结果。

           自定义View的绘图方法为:

    1. 1 //存在canvas对象,即存在默认的显示区域  
      2     @Override  
      3     public void draw(Canvas canvas) {  
      4          //canvas绘图  
      5         }  


          SurfaceView的绘图方法为,例如:

    1 SurfaceView  surfaceView = new MySurfaceView() ;         //创建一个Surface对象  
    2 SurfaceHolder surfaceHolder = surfaceView. getHolder() ;  //获得SurfaceHolder对象  
    3 Canvas   canvas  = surfaceHolder.lockCanvas() ;          //获得canvas对象  
    4 //进行绘图操作  
    5 surfaceHolder.unlockCanvasAndPost(canvas) ;            //释放canvas锁,并且显示视图  

        2、  在其他情形下,我们需要通过代码创建一个Canvas对象,并且在绘画成功后,将该画图区域转换为Drawable图片

      或者通过setBitmap(bitmap)显现出来。一般步骤为: 

    1.  1 //创建一个的Bitmap对象   
       2   
       3    Bitmap bitmap = Bitmap.createBitmap(200, 100, Config.ARGB_8888) ;  
       4   //创建一个canvas对象,并且开始绘图  
       5    Canvas canvas = new Canvas (bitmap) ;  
       6   
       7   ImageView imgView  = new ImageView(this) ;  //或者其他可以设置背景图片的View控件  
       8    
       9   
      10    //为ImageView设置图像  
      11    //将Bitmap对象转换为Drawable图像资  
      12    Drawable drawable = new BitmapDrawable(bitmap) ;  
      13   imgView .setBackgroundDrawable(drawable) ;  
      14   
      15   
      16   或者简单点:  imgView  .setImageBitmap(bitmap);     

         这两种方式都可以显示我们的绘图。
     

     Canvas方法分析:

             clipXXX()方法族

               说明:在当前的画图区域裁剪(clip)出一个新的画图区域,这个画图区域就是canvas对象的当前画图区域了。

                  例如:clipRect(new Rect()),那么该矩形区域就是canvas的当前画图区域了。

            public int save()

               说明:保存已经由canvas绘画出来的东西,在save()和restore()方法之间的操作不对它们造成影响,例如旋转(roate)等。

                   而且对canvas的操作(roate和translate)都是临时的,restore()后不再存在。

           public voidrestore()

               说明:复原sava()方法之前保存的东西资源。

           drawXXX()方法族

               说明:以一定的坐标值在当前画图区域画图。

               注意:图层会叠加,即后面绘画的图层会覆盖前面绘画的图层。

     需要注意的方法是:

         public voiddrawRect(float left, float top, float right, float bottom,Paint paint)

               说明:绘制一个矩型。需要注明的是绘制矩形的参数和Java中的方法不一样。

                  该方法的参数图解说明如下:

            各位看官请注意:图中X、Y轴方向标记错误。 自己也懒得重新修正了。

     

               

               那么,矩形的高 height = bottom  - right 

                          矩形的宽 width  = right – left

           PS :假如drawRect的参数有误,比如right < left ,Android是不会给我们检查的,也不会提示相应的错误信息,

               但它会绘画出一个高或宽很小的矩形,可能不是你希望的。

      

          public voidtranslate(float dx, float dy)

              说明:在当前的坐标上平移(x,y)个像素单位

                        若dx <0 ,沿x轴向上平移; dx >0  沿x轴向下平移

                        若dy <0 ,沿y轴向上平移; dy >0  沿y轴向下平移

         public void rotate(float degrees)

              说明:旋转一定的角度绘制图像。

             

             PS :从截图上看,图像是确实旋转了,但是我找不到旋转的依据中心。

    下面给出该Demo的截图,可以更改一些参数后自己观察效果。

      1、布局文件 main.xkl :  采用了两个ImageView来显示bitmap绘图对象, 让后采用了一个自定义View绘图

     
    1.  1 <?xml version="1.0" encoding="utf-8"?>  
       2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
       3     android:orientation="vertical" android:layout_width="fill_parent"  
       4     android:layout_height="fill_parent">  
       5   
       6     <View android:layout_width="fill_parent" android:layout_height="2dip" android:background="#800080" android:layout_marginTop="2dip"></View>  
       7     <TextView android:layout_width="fill_parent"  
       8         android:layout_height="wrap_content" android:text="<strong>显示canvas区域以及clip方法的使用"</strong> />  
       9   
      10     <ImageView android:id="@+id/imgClip" android:layout_width="fill_parent"  
      11         android:layout_height="wrap_content" android:layout_marginTop="10dip" />  
      12   
      13     <View android:layout_width="fill_parent" android:layout_height="2dip" android:background="#800080" android:layout_marginTop="2dip"></View>  
      14     <TextView android:layout_width="fill_parent"  
      15         android:layout_height="wrap_content" android:text="<strong>save方法和restore方法的使用"</strong> />  
      16     <ImageView android:id="@+id/imgSave" android:layout_width="fill_parent"  
      17         android:layout_height="wrap_content" android:layout_marginTop="10dip" />  
      18   
      19     <View android:layout_width="fill_parent" android:layout_height="2dip" android:background="#800080" android:layout_marginTop="2dip"></View>  
      20     <TextView android:layout_width="fill_parent"  
      21         android:layout_height="wrap_content" android:text="<strong>自定义View,获得了一个Canvas对象和绘图区域</strong>" />  
      22     <com.qin.canvas.MyView android:id="@+id/myView"  
      23         android:layout_width="fill_parent" android:layout_height="200px" />  
      24   
      25 </LinearLayout>  


        2、自定义View  , MyView.java,

     
    1.  1 import android.content.Context;  
       2 import android.graphics.Bitmap;  
       3 import android.graphics.BitmapFactory;  
       4 import android.graphics.Canvas;  
       5 import android.graphics.Color;  
       6 import android.graphics.Paint;  
       7 import android.graphics.Typeface;  
       8 import android.graphics.Bitmap.Config;  
       9 import android.util.AttributeSet;  
      10 import android.view.View;  
      11   
      12 public class MyView extends View{  
      13   
      14     private Paint paint  = new Paint() ;  
      15       
      16     public MyView(Context context) {  
      17         super(context);  
      18         // TODO Auto-generated constructor stub  
      19     }  
      20     public MyView(Context context , AttributeSet attrs){  
      21         super(context,attrs);  
      22     }  
      23     //存在canvas对象,即存在默认的显示区域  
      24     @Override  
      25     public void draw(Canvas canvas) {  
      26         // TODO Auto-generated method stub  
      27         super.draw(canvas);  
      28         //加粗  
      29         paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));  
      30         paint.setColor(Color.BLUE);  
      31         canvas.drawText("自定义View,canvas对象已经存在。", 30, 40, paint);  
      32         canvas.drawRect(10, 10, 30, 30, paint);  
      33           
      34         //将icon图像转换为Bitmap对象  
      35         Bitmap iconbit = BitmapFactory.decodeResource(getResources(), R.drawable.icon) ;  
      36         canvas.drawBitmap(iconbit, 40,40, paint);  
      37     }  
      38 }  


      3、主工程文件 MainActivity.java

    1.  1 public class MainActivity extends Activity {  
       2     //画笔对象 paint  
       3     private Paint paint = new Paint() ;   //记得要为paint设置颜色,否则 看不到效果  
       4     private ImageView imgClip ;  // 绘图区域以及clip方法  
       5     private ImageView imgSave ;  // save方法以及restore  
       6       
       7     /** Called when the activity is first created. */  
       8     @Override  
       9     public void onCreate(Bundle savedInstanceState) {  
      10         super.onCreate(savedInstanceState);  
      11           setContentView(R.layout.main) ;  
      12             
      13           imgClip = (ImageView)findViewById(R.id.imgClip) ;  
      14           imgSave = (ImageView)findViewById(R.id.imgSave);  
      15             
      16           clip_drawCanvas() ; // 绘图区域以及clip方法  
      17           save_drawCanvas();  // save方法以及restore  
      18     }  
      19     //这样的情况下,需要创建Canvas对象,然后在此对象上进行操作  
      20     //对bitmap操作完成后,,显示该Bitmap有以下两种操作。  
      21     //1、需要将bitmap转换为Drawable对象  Drawable drawable = new BitmapDrawable(bitmap) ;  
      22     //2、直接setImageBitmap(bitmap)  
      23     private void  clip_drawCanvas(){  
      24         //将icon图像转换为Bitmap对象  
      25         Bitmap iconbit = BitmapFactory.decodeResource(getResources(), R.drawable.icon) ;  
      26           
      27         //创建一个的Bitmap对象  
      28         Bitmap bitmap = Bitmap.createBitmap(200, 150, Config.ARGB_8888)  ;  
      29           
      30         Canvas canvas = new Canvas (bitmap) ;  
      31         //设置颜色来显示画图区域  
      32         canvas.drawColor(Color.RED);  
      33   
      34         paint.setColor(Color.BLACK);  
      35         canvas.drawText("原先的画图区域--红色部分", 60,50,paint) ;  
      36         //画bitmap对象  
      37         canvas.drawBitmap(iconbit, 20, 20, paint);  
      38           
      39         //剪裁一个区域,当前的操作对象为Rect裁剪的区域  
      40         Rect rect = new Rect (10,80,180,120) ;  
      41           
      42         //当前的画图区域为Rect裁剪的区域,而不是我们之前赋值的bitmap  
      43         canvas.clipRect(rect)  ;  
      44         canvas.drawColor(Color.YELLOW);  
      45         //设置颜色来显示画图区域  
      46         paint.setColor(Color.BLACK);  
      47         canvas.drawText("裁剪clip后画图区域-黄色部分", 10,100,paint) ;  
      48           
      49         //将Bitmap对象转换为Drawable图像资源  
      50         //Drawable drawable = new BitmapDrawable(bitmap) ;  
      51         //img.setBackgroundDrawable(drawable) ;  
      52           
      53         //显示,同上  
      54         imgClip.setImageBitmap(bitmap);  
      55     }  
      56       
      57     private void save_drawCanvas(){  
      58         //将icon图像转换为Bitmap对象  
      59         Bitmap iconbit = BitmapFactory.decodeResource(getResources(), R.drawable.icon) ;  
      60           
      61         //创建一个的Bitmap对象  
      62         Bitmap bitmap = Bitmap.createBitmap(200, 100, Config.ARGB_8888)  ;  
      63      
      64         Canvas canvas = new Canvas (bitmap) ;  
      65   
      66         paint.setColor(Color.GREEN);  
      67         paint.setTextSize(16);  //设置字体大小  
      68         canvas.drawRect(10, 10, 50, 8, paint);  
      69         canvas.drawText("我没有旋转",50, 10, paint);  
      70         //保存canvas之前的操作,在sava()和restore之间的操作不会对canvas之前的操作进行影响  
      71         canvas.save() ;  
      72           
      73         //顺时针旋转30度  
      74         canvas.rotate(30) ;  
      75         canvas.drawColor(Color.RED);  
      76         canvas.drawBitmap(iconbit, 20, 20, paint);  
      77         canvas.drawRect(50, 10, 80, 50, paint);  
      78         //canvas.translate(20,20);  
      79         canvas.drawText("我是旋转的",115,20, paint);  
      80           
      81         //复原之前save()之前的属性,并且将save()方法之后的roate(),translate()以及clipXXX()方法的操作清空  
      82         canvas.restore();  
      83           
      84         //平移(20,20)个像素  
      85         //canvas.translate(20,20);  
      86         canvas.drawRect(80, 10, 110,30, paint);  
      87         canvas.drawText("我没有旋转",115,20, paint);  
      88   
      89         //将Bitmap对象转换为Drawable图像资  
      90         //为ImageView设置图像  
      91         //imgSave.setImageBitmap(bitmap);  
      92           
      93         Drawable drawable = new BitmapDrawable(bitmap) ;  
      94         imgSave.setBackgroundDrawable(drawable) ;  
      95           
      96     }  
      97 }  


              总的来说,Canvas理解起来还是比较纠结的,尤其是它的几个方法真是让人头疼, 希望你能够自己编写相应的代码

      理解透彻,才真正的有所收获。

  • 相关阅读:
    POJ 3259 Wormholes【BellmanFord】
    POJ 2960 SNim【SG函数的应用】
    ZOJ 3578 Matrixdp水题
    HDU 2897 邂逅明下【bash博弈】
    BellmanFord 算法及其优化【转】
    【转】几个Java的网络爬虫
    thinkphp 反字符 去标签 自动加点 去换行 截取字符串 冰糖
    php 二维数组转 json文本 (jquery datagrid 数据格式) 冰糖
    PHP 汉字转拼音(首拼音,所有拼音) 冰糖
    设为首页与加入收藏 兼容firefox 冰糖
  • 原文地址:https://www.cnblogs.com/Sharley/p/5563574.html
Copyright © 2011-2022 走看看