Andriod中绘(画)图----Canvas的使用详解

                                                                                                          

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

 

 

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

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

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

  

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

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

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

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

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

   

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

 

    我们打个简单的比方吧:

                Paint        就是画笔

                Bitmap    就是画布

                Canvas   就是画家

 

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

 

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

 

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

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

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

 

       自定义View的绘图方法为:

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


      SurfaceView的绘图方法为,例如:

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

 

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

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

   //创建一个的Bitmap对象 
Bitmap bitmap = Bitmap.createBitmap(200, 100, Config.ARGB_8888) ;
//创建一个canvas对象,并且开始绘图
Canvas canvas = new Canvas (bitmap) ;
ImageView imgView  = new ImageView(this) ;  //或者其他可以设置背景图片的View控件
//为ImageView设置图像
//将Bitmap对象转换为Drawable图像资
Drawable drawable = new BitmapDrawable(bitmap) ;
imgView .setBackgroundDrawable(drawable) ;
或者简单点:  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绘图

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<View android:layout_width="fill_parent" android:layout_height="2dip" android:background="#800080" android:layout_marginTop="2dip"></View>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="显示canvas区域以及clip方法的使用" />
<ImageView android:id="@+id/imgClip" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_marginTop="10dip" />
<View android:layout_width="fill_parent" android:layout_height="2dip" android:background="#800080" android:layout_marginTop="2dip"></View>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="save方法和restore方法的使用" />
<ImageView android:id="@+id/imgSave" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_marginTop="10dip" />
<View android:layout_width="fill_parent" android:layout_height="2dip" android:background="#800080" android:layout_marginTop="2dip"></View>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="自定义View,获得了一个Canvas对象和绘图区域" />
<com.qin.canvas.MyView android:id="@+id/myView"
android:layout_width="fill_parent" android:layout_height="200px" />
</LinearLayout>


    2、自定义View  , MyView.java,

 

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.Bitmap.Config;
import android.util.AttributeSet;
import android.view.View;
public class MyView extends View{
private Paint paint  = new Paint() ;
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public MyView(Context context , AttributeSet attrs){
super(context,attrs);
}
//存在canvas对象,即存在默认的显示区域
@Override
public void draw(Canvas canvas) {
// TODO Auto-generated method stub
super.draw(canvas);
//加粗
paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
paint.setColor(Color.BLUE);
canvas.drawText("自定义View,canvas对象已经存在。", 30, 40, paint);
canvas.drawRect(10, 10, 30, 30, paint);
//将icon图像转换为Bitmap对象
Bitmap iconbit = BitmapFactory.decodeResource(getResources(), R.drawable.icon) ;
canvas.drawBitmap(iconbit, 40,40, paint);
}
}


  3、主工程文件 MainActivity.java

 

public class MainActivity extends Activity {
//画笔对象 paint
private Paint paint = new Paint() ;   //记得要为paint设置颜色,否则 看不到效果
private ImageView imgClip ;  // 绘图区域以及clip方法
private ImageView imgSave ;  // save方法以及restore
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main) ;
imgClip = (ImageView)findViewById(R.id.imgClip) ;
imgSave = (ImageView)findViewById(R.id.imgSave);
clip_drawCanvas() ; // 绘图区域以及clip方法
save_drawCanvas();  // save方法以及restore
}
//这样的情况下,需要创建Canvas对象,然后在此对象上进行操作
//对bitmap操作完成后,,显示该Bitmap有以下两种操作。
//1、需要将bitmap转换为Drawable对象  Drawable drawable = new BitmapDrawable(bitmap) ;
//2、直接setImageBitmap(bitmap)
private void  clip_drawCanvas(){
//将icon图像转换为Bitmap对象
Bitmap iconbit = BitmapFactory.decodeResource(getResources(), R.drawable.icon) ;
//创建一个的Bitmap对象
Bitmap bitmap = Bitmap.createBitmap(200, 150, Config.ARGB_8888)  ;
Canvas canvas = new Canvas (bitmap) ;
//设置颜色来显示画图区域
canvas.drawColor(Color.RED);
paint.setColor(Color.BLACK);
canvas.drawText("原先的画图区域--红色部分", 60,50,paint) ;
//画bitmap对象
canvas.drawBitmap(iconbit, 20, 20, paint);
//剪裁一个区域,当前的操作对象为Rect裁剪的区域
Rect rect = new Rect (10,80,180,120) ;
//当前的画图区域为Rect裁剪的区域,而不是我们之前赋值的bitmap
canvas.clipRect(rect)  ;
canvas.drawColor(Color.YELLOW);
//设置颜色来显示画图区域
paint.setColor(Color.BLACK);
canvas.drawText("裁剪clip后画图区域-黄色部分", 10,100,paint) ;
//将Bitmap对象转换为Drawable图像资源
//Drawable drawable = new BitmapDrawable(bitmap) ;
//img.setBackgroundDrawable(drawable) ;
//显示,同上
imgClip.setImageBitmap(bitmap);
}
private void save_drawCanvas(){
//将icon图像转换为Bitmap对象
Bitmap iconbit = BitmapFactory.decodeResource(getResources(), R.drawable.icon) ;
//创建一个的Bitmap对象
Bitmap bitmap = Bitmap.createBitmap(200, 100, Config.ARGB_8888)  ;
Canvas canvas = new Canvas (bitmap) ;
paint.setColor(Color.GREEN);
paint.setTextSize(16);  //设置字体大小
canvas.drawRect(10, 10, 50, 8, paint);
canvas.drawText("我没有旋转",50, 10, paint);
//保存canvas之前的操作,在sava()和restore之间的操作不会对canvas之前的操作进行影响
canvas.save() ;
//顺时针旋转30度
canvas.rotate(30) ;
canvas.drawColor(Color.RED);
canvas.drawBitmap(iconbit, 20, 20, paint);
canvas.drawRect(50, 10, 80, 50, paint);
//canvas.translate(20,20);
canvas.drawText("我是旋转的",115,20, paint);
//复原之前save()之前的属性,并且将save()方法之后的roate(),translate()以及clipXXX()方法的操作清空
canvas.restore();
//平移(20,20)个像素
//canvas.translate(20,20);
canvas.drawRect(80, 10, 110,30, paint);
canvas.drawText("我没有旋转",115,20, paint);
//将Bitmap对象转换为Drawable图像资
//为ImageView设置图像
//imgSave.setImageBitmap(bitmap);
Drawable drawable = new BitmapDrawable(bitmap) ;
imgSave.setBackgroundDrawable(drawable) ;
}
}


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

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


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/62642.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用plot,hist等函数画各种图示

hist函数&#xff0c;给定一堆数据&#xff0c;统计数据在某一值的个数。plot是给定横/纵坐标向量&#xff0c;描绘点列。 统计频率---hist 第一步&#xff1a;用load导入文本数据&#xff0c;Matlab会自动生成以文件名命名的二维矩阵; 第二步&#xff1a;按列或按行取出所需要…

如何优雅地画一张图

作者&#xff1a;不近视的猫 转载地址&#xff1a;https://juejin.cn/post/7105110185768648711 前言 在 Flutter 中&#xff0c;若我们需要自定义画一张图&#xff0c;则需要用到 CustomPaint&#xff0c;不过 CustomPaint 并不是本篇文章的重点&#xff0c;所以我就直接贴出…

chatgpt赋能python:使用Python建立数据库

使用Python建立数据库 在当今的数字时代&#xff0c;数据是无处不在的。企业、政府甚至个人都需要存储和管理他们的数据以支持他们的工作。数据库就成为了一个必不可少的工具。在本文中&#xff0c;我们将介绍如何使用Python来创建数据库。 什么是数据库&#xff1f; 一个数…

盘点一个Python网络爬虫问题

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 在天愿作比翼鸟&#xff0c;在地愿为连理枝。 大家好&#xff0c;我是皮皮。 一、前言 前几天在Python最强王者群【刘桓鸣】问了一个Python网络爬虫的问…

请问这个网址怎么用httpx 把json数据取出来

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 空山新雨后&#xff0c;天气晚来秋。 大家好&#xff0c;我是皮皮。 一、前言 前几天在Python铂金群【gyx】问了一个Python网络爬虫处理的问题&#xf…

大伙,为啥我爬虫爬百度搜索得出的结果是0啊?

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 君王掩面救不得&#xff0c;回看血泪相和流。 大家好&#xff0c;我是皮皮。 一、前言 前几天在Python白银交流群【~Crazy】问了一个Python网络爬虫处理…

Python网络爬虫,我目前只能获取单个文件,为啥?

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 归来池苑皆依旧&#xff0c;太液芙蓉未央柳。 大家好&#xff0c;我是皮皮。 一、前言 前几天在Python钻石交流群【Jethro Shen】问了一个Python网络爬…

盘点一个Python网络爬虫过验证码的问题(方法一)

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 低眉信手续续弹&#xff0c;说尽心中无限事。 大家好&#xff0c;我是皮皮。 一、前言 前几天在Python最强王者群【鶏啊鶏。】问了一个Python网络爬虫的…

小红书怎么推广笔记?小红书推广笔记有什么用?

小红书平台问世以来&#xff0c;得到快速发展&#xff0c;目前已经是电商领域的后起之秀&#xff0c;也是重要的口碑平台&#xff0c;在女性及生活用品方面的影响力不次于微信和微博&#xff0c;可以说是和抖音齐名的新秀平台。大家都知达到小红书平台的重要重要性&#xff0c;…

小红书笔记下沉的方法和技巧

小红书目前用户越来越多&#xff0c;随之而来发布的笔记数量也大了起来&#xff0c;不可避免得出现很多恶意的负面笔记&#xff0c;让大家很头疼。 下面推神网&#xff08;daizuobaike&#xff09;就给大家详细介绍下几种小红书负面笔记处理的方式: 1.官方入口&#xff0c;达到…

3.13 小红书笔记怎样带话题,才能增加曝光?【玩赚小红书】

虽然很多博主都知道在笔记内容最后要带上一个相关话题&#xff0c;但却很少人知道带什么样的话题&#xff0c;如何找到官方话题或热门话题来提高笔记内容的曝光。这一篇文章黄宇风就来讲讲&#xff0c;小红书笔记该如何带话题。 ​ ​ 1、挖掘小红书笔记热门话题 笔记带话题主…

小红书笔记没人看是什么原因?账号正常吗

相信很多人都遇到过自己认为笔记质量不错&#xff0c;但仍然会出现发布的小红书笔记没人看的情况。我们将为大家分析可能是哪些原因造成了这方面的困境&#xff0c;并告诉大家应该如何解决这些问题。 一&#xff0e;小红书笔记没人看的原因 1.账号违规 如果账号本身昵称、个性…

小红书怎样找回原账号_小红书笔记数据好不好,关键词搜索占一半

用户获取、浏览小红书笔记的渠道大致可以分为四个&#xff0c;一个是关注的博主账号&#xff0c;首页会有他们的笔记内容推荐;一个是主页上的发现页面&#xff0c;会推荐平常该用户感兴趣的内容以及附近地点的笔记;另外还有的则是小红书系统推荐。但更多小红书用户平常看笔记、…

小红书笔记打开显示连接不到服务器,小红书笔记看不到全文怎么回事啊?怎么发布小红书笔记?...

我们可以通过小红书购物笔记了解一些商品哦&#xff0c;因为小红书购物笔记里面的内容基本都是一些买家的购物体验&#xff0c;对于要买东西的我们来说&#xff0c;可以提供一些建议。可是最近有网友咨询小红书笔记看不到全文&#xff0c;小红书购物笔记找不到怎么回事?怎么发…

与领导吃饭需要注意什么

虽然说招待客人需要一定的技巧&#xff0c;但不是所有的聚餐&#xff0c;对方都会答应宴请&#xff1b;尤其是下属请领导吃饭时&#xff0c;不仅需要各种礼仪&#xff0c;还需要一定的技巧&#xff1b;当领导遇到下属&#xff0c;要请客吃饭时&#xff0c;都认为下属是有目的的…

新来的领导把我的职务免掉了,一年后,我要不要找领导聊聊?

你这一年都不找领导聊&#xff0c;现在人家另外两个都官复原职了&#xff0c;你才想起来聊聊&#xff0c;晚了。 从你的叙述中可以看出&#xff0c;你是一个非常正直的人&#xff0c;要不然被免职后也不会这么干等着。但正是你的正直&#xff0c;才导致了复职的是另外两个 &am…

领导找你谈话要注意这些

我的朋友小单每天努力工作&#xff0c;得到领导的重视&#xff1b;有一次小单正在认真工作&#xff0c;领导突然把小单叫到办公室谈话。小单一开始还有些紧张&#xff0c;没想到领导正好找她谈心&#xff0c;小单明白了领导的目的后就开口说话了。领导表面上只是问&#xff0c;…

如何看待程序员休息时间不工作被领导威胁辞退的?

在现在的互联网行业&#xff0c;程序员在职场工作肯定是十分辛苦的&#xff0c;基本很多公司都是996制度&#xff0c;这也和互联网行业工作环境有关系。因此程序员基本就只有周末一天假&#xff0c;所以难得休息一下。就有一名程序员因为在休息时间不工作被领导威胁辞退&#x…

程序员被领导辞退,1周后接到领导电话,听完后网友:把他拉黑

员工离职后&#xff0c;跟原来的单位就不再是雇佣关系&#xff0c;如果原单位有事情需要员工帮着解决&#xff0c;员工该不该收取报酬呢&#xff0c;但有的老板却认为&#xff0c;员工当时在公司留下的后遗症&#xff0c;他帮着公司解决&#xff0c;理所当然。 最近有一位程序员…

程序员和领导聚餐晒图,网友回复亮了:发量上就知道谁是新来的

目前大家都知道现在互联网行业的高薪&#xff0c;另外随着互联网行业们&#xff0c;门槛的降低&#xff0c;有很多人都想要加入到和联网行业当中来&#xff0c;而薪资高待遇好也是程序员让人羡慕的一方面&#xff0c;虽然一方面吐槽你互联网行业的辛苦加班&#xff0c;没有个人…