GVKun编程网logo

canvas的使用方法(canvas的使用步骤)

12

对于想了解canvas的使用方法的读者,本文将提供新的信息,我们将详细介绍canvas的使用步骤,并且为您提供关于Android中View.onDraw(Canvascanvas)的使用方法、andr

对于想了解canvas的使用方法的读者,本文将提供新的信息,我们将详细介绍canvas的使用步骤,并且为您提供关于Android 中View.onDraw(Canvas canvas)的使用方法、android-canvas(一) scale(缩放)的使用、Android中Canvas的常用方法总结、Android中自定义视图View之---进阶篇(Canvas的使用)的有价值信息。

本文目录一览:

canvas的使用方法(canvas的使用步骤)

canvas的使用方法(canvas的使用步骤)

了解canvas:canvas标签是用作图形绘制,但是通过js脚本来实现的,canvas标签其实只是一个容器

,最终实现绘制功能肯定是通过js脚本实现。

首先肯定要定义一个canvas标签当做容器

<canvas id="myCanvas" width="200" height="100"></canvas>

canvas 元素本身是没有绘图能力的。所有的绘制工作必须在 JavaScript 内部完成,所以需要获取画布对象,绘制的方法和属性就在创建的ctx对象的方法和属性上:

var c=document.getElementById("myCanvas");

var ctx=c.getContext("2d");

ctx属性和方法:

1:fillstyle属性 : CSS颜色,渐变,或图案。fillStyle 默认设置是#000000(黑色)

ctx.fill;

2:fillsReact方法:方法定义了矩形当前的填充方式。 x,y 起点的坐标   width height 绘制的宽高

ctx.fillRect(0,0,150,75);

3:

在Canvas上画线,我们将使用以下两种方法:

moveTo(x,y) 定义线条开始坐标
lineTo(x,y) 定义线条结束坐标
闭合即可,上一个终点可以是下一个起点,这样可以用线绘制图形

stroke() 方法闭合即可 .

4:canvas 绘制文本

font - 定义字体
fillText(text,x,y) - 在 canvas 上绘制实心的文本
strokeText(text,x,y) - 在 canvas 上绘制空心的文本
使用 fillText():

var c=document.getElementById("myCanvas");

var ctx=c.getContext("2d");

ctx.font="30px Arial";

ctx.fillText("Hello World",10,50);

5 Canvas - 图像
把一幅图像放置到画布上, 使用以下方法:

var c=document.getElementById("myCanvas");

var ctx=c.getContext("2d");

var img=document.getElementById("scream");

ctx.drawImage(img,10,10);

  

Android 中View.onDraw(Canvas canvas)的使用方法

Android 中View.onDraw(Canvas canvas)的使用方法

Android 中View.onDraw(Canvas canvas)的使用方法

View通过View.onDraw(Canvas canvas)来Draw.

我们可以定义自己的继承于View的TestView,然后重载View.onDraw(Canvas canvas).

对于自定义的TestView如何与Activity关联?有以下两种方式:

  1. 直接在setContentView(View view)里面加进去自定义的View:setContentView(new TestView(this)).
  2. 另外,可以在layout文件里面可以使用自定义的View(如何自定义的View为内部类,就会失效),

如:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  xmlns:android="http://schemas.android.com/apk/res/android"> 
  <com.android.test.TestView 
    android:id="@+id/testview" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"/> 
</FrameLayout> 

 以下为使用onDraw(Canvas canvas)画矩形区域,及在其上画文本的实例(通过使用内部类使程序显得更加简洁,紧凑):

package com.android.test; 
import android.app.Activity; 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Rect; 
import android.graphics.Typeface; 
import android.os.Bundle; 
import android.view.View; 
public class TestActivity extends Activity { 
  /** Called when the activity is first created. */ 
  @Override 
  public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(new TestView(this)); 
  } 
  public class TestView extends View { 
    private Paint mPaint = new Paint(); 
    public TestView(Context context) { 
      super(context); 
    } 
     
    @Override 
    protected void onDraw(Canvas canvas) { 
      // Todo Auto-generated method stub 
      super.onDraw(canvas); 
       
      String text = "Android - 机器人";      
      mPaint.setColor(Color.WHITE); 
       
      Paint paint = new Paint(); 
      paint.setColor(Color.RED); 
       
      String familyName = "宋体"; 
      Typeface font = Typeface.create(familyName,Typeface.BOLD); 
      paint.setTypeface(font); 
       
      paint.setTextSize(22); 
       
      canvas.drawRect(new Rect(0,320,240),mPaint); 
      canvas.drawText(text,100,paint); 
    } 
  } 
} 

 运行效果如下图:

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

android-canvas(一) scale(缩放)的使用

android-canvas(一) scale(缩放)的使用

在android下缩放可以实现onDraw下的画笔画的内容变小,这里以文本为例进行讲解。

scale提供的方法

  在cale提供了两个方法
  public void scale(float sx, float sy)
  public final void scale(float sx, float sy, float px, float py)

scale(float sx, float sy)

这是一个以0,0为基准的缩放,它会以父布局的坐标(0,0)到(float sx, float sy)做为
一个矩形框,	如果是缩放,会移动所画的文字的位置	下面的代码onDraw()画
的缩放0.5的布局
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.GREEN);
        canvas.drawText("base", 0, 400, paintOuterText);
        canvas.scale(1.0F, 0.5F);
        canvas.drawText("base-0.5" , 0, 400, paintOuterText);
        canvas.scale(1.0F, 0.5F);
        canvas.drawText("base-0.5*0.5" , 0, 400, paintOuterText);
    }
效果图如下,可以看出来第一次文字的缩放显示的位置是400的一半,而第二次
显示是200的一半

无

	如果我们想要每次都画在400的一半上,那可以这么处理,引入save()和restore()机制,
	在第一次缩放画,保存画布的状态,第一次画完时,还原画布的状态	
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.GREEN);
        canvas.drawText("base", 0, 400, paintOuterText);
        canvas.save();
        canvas.scale(1.0F, 0.5F);
        canvas.drawText("    base-0.5" , 0, 400, paintOuterText);
        canvas.restore();
        canvas.scale(1.0F, 0.5F);
        canvas.drawText("base-0.5*0.5" , 0, 400, paintOuterText);
    }
  效果图如下

无

scale(float sx, float sy, float px, float py)

这是一个定义一个以某个坐标为基准的缩放,他可以实现以某一个坐标的缩放,这个是我们
需要的效果
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.GREEN);
        canvas.drawText("base", 0, 400, paintOuterText);
        canvas.scale(1.0F, 0.5F,0,400);
        canvas.drawText("    base-0.5", 0, 400, paintOuterText);
        canvas.scale(1.0F, 0.5F,0,400);
        canvas.drawText("base-0.5*0.5", 0, 400, paintOuterText);
    }

效果图如下

sdf

Android中Canvas的常用方法总结

Android中Canvas的常用方法总结

一、对Canvas进行操作

对Canvas的一系列操作,是指对Canvas进行旋转、平移、缩放等操作。

这些操作可以让Canvas对象使用起来更加便捷。

二、Canvas平移

/** 
 * 画布向(100,50)方向平移 
 * 
 * 参数1: 向X轴方向移动100距离 
 * 参数2: 向Y轴方向移动50距离 
 */
 canvas.translate(100,50);

三、Canvas缩放

/** 
 * 在X轴方向放大为原来2倍,Y轴方向方大为原来的4倍 
 * 参数1: X轴的放大倍数 
 * 参数2: Y轴的放大倍数 
 */
canvas.scale(2,4);

/** 
 * 在X轴方向放大为原来2倍,Y轴方向方大为原来的4倍 
 * 参数1: X轴的放大倍数 
 * 参数2: Y轴的放大倍数 
 * 参数3: 原点X坐标
 * 参数4: 原点Y坐标
 */
canvas.scale(2,4,100,100);


四、Canvas旋转

/** 
 * 原点为中心,旋转30度(顺时针方向为正方向 )
 * 参数: 旋转角度 
 */
canvas.rotate(30);

/** 
 * 以(100,100)为中心,旋转30度,顺时针方向为正方向 
 * 参数: 旋转角度 
 */
canvas.rotate(30,100,100);


五、Canvas操作例子

 Paint p = new Paint();
 p.setColor(Color.argb(50,255,100));
 canvas.drawRect(0,200,p); // 以原始Canvas画出一个矩形1
 canvas.translate(300,300); // 将Canvas平移 (100,100)
 p.setColor(Color.argb(50,p); // 矩形2
 canvas.rotate(30); //将Canvas旋转30
 p.setColor(Color.argb(50,255));
 canvas.drawRect(0,p); // 矩形3
 canvas.scale(2,2); // 将Canvas以原点为中心,放大两倍
 p.setColor(Color.argb(50,0));
 canvas.drawRect(0,p); // 矩形4

六、Canvas保存和还原

Canvas提供了几个方法,让我们可以方便的对Canvas的状态进行更改和还原。

这些方法是:save() restore() restoretoCount(int saveCount)

我们在对Canvas进行平移、旋转、放大等操作时候,可以调用save()方法,将当前修改过的Canvas状态进行保存,调用restore() 方法后,会将Canvas还原成最近的一个save() 的状态。

save()方法还会有一个返回值,我们也可以调用restoretoCount(int saveCount)方法,将这个返回值作为参数传递进去,就可以将Canvas还原成某一个特定的save()状态。

 canvas.translate(100,100); // 平移(100,100)
 int save1 = canvas.save(); // 保存Canvas状态(状态1)
 canvas.scale(2,2); // 放大2倍
 int save2 = canvas.save(); // 保存Canvas状态(状态2)
 canvas.restore(); // 返回最新的save状态,即状态2
 canvas.restoretoCount(save1);// 手动指定的返回到 状态1

六、Canvas画图实例

1、画文字

/** 
 * 参数2:文本的x轴的开始位置 
 * 参数2:文本Y轴的结束位置 
 * 参数3:画笔对象 
 */ 
canvas.drawText("开始写字了!",50,p);// 画文本 

/** 
 * 参数2:要从第几个字开始绘制 
 * 参数3:要绘制到第几个文字 
 * 参数4:文本的x轴的开始位置 
 * 参数5:文本Y轴的结束位置 
 * 参数6:画笔对象 
 */ 
canvas.drawText("开始写字了!",2,5,p);// 画文本,结果为:“写字了” 
/** 
 * 参数2:路径 
 * 参数3:距离路径开始位置的偏移量 
 * 参数4:距离路径上下的偏移量(可以为负数) 
 * 参数5:画笔对象 
 */ 
canvas.drawTextOnPath("1234567890101123123",path,-50,p);

2、画圆

/**
 * 参数1:圆心X 
 * 参数2:圆心Y 
 * 参数3:半径R 
 * 参数4:画笔对象 
 */   
canvas.drawCircle(200,p);

3、画线

/* 
 * 参数1:startX 
 * 参数2:startY 
 * 参数3:stopX 
 * 参数4:stopY 
 * 参数5:画笔对象 
 */ 
canvas.drawLine(100,300,p);// 画线 
/* 
 * 同时绘制多条线。 
 * 参数1:float数组:每四个一组为一条线。最后不足四个,就忽略那些值。 
 * 参数2:画笔对象 
 */ 
canvas.drawLines(new float[]{100,100},p);

4、画椭圆

/* 
 * 参数1:float left 
 * 参数2:float top 
 * 参数3:float right 
 * 参数4:float bottom 
 */ 
RectF oval = new RectF(150,500,400);// 画一个椭圆 
canvas.drawoval(oval,p);

5、画弧度

/**
 * 画圆弧
 * 参数1:RectF对象。 
 * 参数2:开始的角度。(水平向右为0度顺时针反向为正方向) 
 * 参数3:扫过的角度 
 * 参数4:是否和中心连线 
 * 参数5:画笔对象 
 */ 
canvas.drawArc(oval,20,180,false,p);

6、矩形

/** 
 * 矩形 
 * 参数1:float left 
 * 参数2:float top 
 * 参数3:float right 
 * 参数4:float bottom 
 */ 
canvas.drawRect(100,p); 

//画圆角矩形 
RectF oval3 = new RectF(80,260,300);// 设置个新的长方形 
canvas.drawRoundRect(oval3,p);//第二个参数是x半径,第三个参数是y半径

7、多边形

/** 
 * Path类封装复合(多轮廓几何图形的路径 
 * 由直线段*、二次曲线,和三次方曲线,也可画以油画。drawPath(路径、油漆),要么已填充的或抚摸 
 * (基于油漆的风格),或者可以用于剪断或画画的文本在路径。 
 */ 
Path path = new Path(); // 路径对象 
path.moveto(80,200);// 此点为多边形的起点 
path.lineto(120,250); 
path.lineto(80,250); 
//.... 可以添加多个点。构成多边形 
path.close(); // 使终点和起点链接,构成封闭图形 
  canvas.drawPath(path,p);

8、画贝塞尔曲线

p.setStyle(Style.stroke); 
Path path2=new Path(); 
path2.moveto(100,100);//设置Path的起点 
/** 
 * 参数1、2:x1,y1为控制点的坐标值 
 * 参数3、4:x2,y2为终点的坐标值 
 */ 
path2.quadTo(300,400,400); //设置贝塞尔曲线的控制点坐标和终点坐标 
path2.quadTo(500,700,800,800); 
canvas.drawPath(path2,p);//画出贝塞尔曲线

9、画点

/** 
 * 参数1、2:点的x、y坐标 
 */ 
canvas.drawPoint(60,390,p);//画一个点 
/** 
 * 参数1:多个点,每两个值为一个点。最后个数不够两个的值,忽略。 
 */ 
canvas.drawPoints(new float[]{60,65,70,400},p);//画多个点

10、画图片

Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher); 
/** 
 * 参数1:bitmap对象 
 * 参数2:图像左边坐标点 
 * 参数3:图像上边坐标点 
 */ 
canvas.drawBitmap(bitmap,p);

七、总结

以上就是这篇文章的全部内容,希望对大家的学习或者工作能有一定的帮助,如果有疑问可以留言留言。

Android中自定义视图View之---进阶篇(Canvas的使用)

Android中自定义视图View之---进阶篇(Canvas的使用)


更多技术内容请移步:我的个人博客

一、前言

今天是周日,昨天刚刚写完了一篇关于如何搭建LNMP环境,让自己可以DIY有个性的个人主页:

http://blog.csdn.net/jiangwei0910410003/article/details/50929955

那么今天,我们继续来看一篇关于Android中的UI篇,如何自定义视图View的进阶篇,关于前奏篇之前已经写过了,还没有了解的同学可以去看看:http://blog.csdn.net/jiangwei0910410003/article/details/42640665,在这篇文章中我主要介绍了自定义View的一些基础知识,讲解了Paint,Canvas,Path,渐变色等技术。那么隔了半年的时间,我们今天再次看一下如何在上一个层次去使用Canvas自定义更多的我们想要的特效呢?说道这里,我还想多讲两句,就是Android中UI知识点还是很多很高深的,如果你对UI技术了解的非常透彻,那么待遇也是很不错的,现在可以看到一些公司在找Android高级UI工程师,就是叫你去做一些酷炫的UI,同时对性能方面也是要了解很多的,因为我们知道酷炫的UI动画什么的,其实如果处理不好会给整个程序造成很大的性能问题。所以本人对Android中的UI和逆向领域非常感兴趣的。


二、知识点&实现的效果

下面我们就来看看,如何使用Canvas做一些我们经常要用到的效果:

1、修改图片的透明度

2、图层的叠加效果(遮罩层)

3、画布的保存和恢复操作

4、使用矩阵实现平移,旋转,缩放动画

5、通过旋转,平移,缩放画布来实现动画

6、裁剪画布

总共六个知识点,讲完这些知识点,现在市面上的View大部分都可以知道原理,以及自己可以动手去绘制了,后面会再写一篇关于自定义ViewGroup系列(LinearLayout,RelativeLayout等)的相关文章。


三、具体实现

我们下面就用例子一一介绍这上面的六个功能点,首先我们先回顾一下,如何自定义一个View,其实很简单,我们只需要集成View类,然后在onDraw方法中,得到一个画布Canvas对象,然后就可以绘制各种我们想要的效果了。

public void onDraw(Canvas canvas)

下面我们先来看看第一个知识点:

1、修改图片的透明度

/**
 * 修改图片的argb值
 * @param sourceImg
 * @param number
 * @return
 */
public static Bitmap getTransparentBitmap(Bitmap sourceImg, int number){
	int[] argb = new int[sourceImg.getWidth() * sourceImg.getHeight()];
	sourceImg.getPixels(argb, 0, sourceImg.getWidth(), 0, 0, sourceImg
			.getWidth(), sourceImg.getHeight());// 获得图片的ARGB值
	number = number * 255 / 100;
	for (int i = 0; i < argb.length; i++) {
		argb[i] = (number << 24) | (argb[i] & 0x00FFFFFF);
	}
	sourceImg = Bitmap.createBitmap(argb, sourceImg.getWidth(), sourceImg
			.getHeight(), Bitmap.Config.ARGB_8888);
	return sourceImg;
}

我们在onDraw方法绘制出修改之后的图片:

BitmapDrawable drawable = (BitmapDrawable)ctx.getResources().getDrawable(R.drawable.cm_whatsapp_ico_audio);
Bitmap bitmap = drawable.getBitmap();

//修改图片的argb值的使用
bitmap = getTransparentBitmap(bitmap, 10);
canvas.drawBitmap(bitmap, 0, 0, paint);
代码其实很简单,就是拿到原图Bitmap,然后在从新构造一张图片,只是这时候我们会看到这里的技术点:

首先我们可以获取到一张图片的ARGB数组值,数组大小就是图片的像素值,那么每个像素都是一个int类型值:

A代表透明度:8位

RGB代表三基色的颜色值:各8位

那么加起来是32位,正好一个int类型长度。

这个也是在构造图片的时候我们可以看到Bitmap.Config.ARGB_8888的含义,当然这个Config还有其他值,比如:

Bitmap.Config.ALPHA_8:只有透明度的值,8位,那么我们可以使用byte类型就可以了。这张图我们可以想象没有颜色的图片。

Bitmap.Config.ARGB_4444:和ARGB.8888类似,就是占用的位数不一样,这里是4*4=16位,用short类型即可,由此可见ARGB.8888虽然能够显示更高清的图片,但是占用内存会高点。

Bitmap.Config.RGB_565:只有颜色值,没有透明度,占用位数:5+6+5=16位,用short类型即可。

就是在构造一张Bitmap的时候,可以传递新的argb值了,那么意味着我们可以随意的改变图片的透明度,颜色值啥的,我们看一下效果:


下面我们在随便改一下他的颜色值:

for (int i = 0; i < argb.length; i++) {
	argb[i] = (number << 24) | (argb[i] & 0x00FFFFFF);
	argb[i] = 400 + (argb[i] & 0xFF00FFFF);
}

看一下效果:


知识点:

1>、我们可以使用Bitmap的getPixel方法获取图片的像素值

2>、了解到了图片像素值的表示含义和各个配置之间的差异

3>、修改图片的透明度和颜色值


2、图层的叠加效果(遮罩层)

这个知识点我们可能在前面已经介绍过了,比如如何制作圆角图片,就是用遮罩层来做的,其实遮罩层说白了,就是两张图片之间如何进行叠加,类似于ppt中我们制作图片的时候,可以选择至于上层,至于底层等效果。但是这里的遮罩层的效果会更多,下面来看一下代码实现:

//获得圆角图片的方法
/**
 *   android.graphics.PorterDuff.Mode.SRC:只绘制源图像
         android.graphics.PorterDuff.Mode.DST:只绘制目标图像
         android.graphics.PorterDuff.Mode.DST_OVER:在源图像的顶部绘制目标图像
         android.graphics.PorterDuff.Mode.DST_IN:只在源图像和目标图像相交的地方绘制目标图像
         android.graphics.PorterDuff.Mode.DST_OUT:只在源图像和目标图像不相交的地方绘制目标图像
         android.graphics.PorterDuff.Mode.DST_ATOP:在源图像和目标图像相交的地方绘制目标图像,在不相交的地方绘制源图像
         android.graphics.PorterDuff.Mode.SRC_OVER:在目标图像的顶部绘制源图像
         android.graphics.PorterDuff.Mode.SRC_IN:只在源图像和目标图像相交的地方绘制源图像
         android.graphics.PorterDuff.Mode.SRC_OUT:只在源图像和目标图像不相交的地方绘制源图像
         android.graphics.PorterDuff.Mode.SRC_ATOP:在源图像和目标图像相交的地方绘制源图像,在不相交的地方绘制目标图像
         android.graphics.PorterDuff.Mode.XOR:在源图像和目标图像重叠之外的任何地方绘制他们,而在不重叠的地方不绘制任何内容
         android.graphics.PorterDuff.Mode.LIGHTEN:获得每个位置上两幅图像中最亮的像素并显示
         android.graphics.PorterDuff.Mode.DARKEN:获得每个位置上两幅图像中最暗的像素并显示
         android.graphics.PorterDuff.Mode.MULTIPLY:将每个位置的两个像素相乘,除以255,然后使用该值创建一个新的像素进行显示。结果颜色=顶部颜色*底部颜色/255
         android.graphics.PorterDuff.Mode.SCREEN:反转每个颜色,执行相同的操作(将他们相乘并除以255),然后再次反转。结果颜色=255-(((255-顶部颜色)*(255-底部颜色))/255)
 * @param bitmap
 * @param roundPx
 * @return
 */
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap,float roundPx){
	Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
			.getHeight(), Bitmap.Config.ARGB_8888);
	Canvas canvas = new Canvas(output);

	final int color = 0xff424242;
	final Paint paint = new Paint();
	final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
	final RectF rectF = new RectF(rect);
	paint.setAntiAlias(true);
	canvas.drawARGB(0, 0, 0, 0);
	paint.setColor(color);
	canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
	paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
	canvas.drawBitmap(bitmap, rect, rect, paint);
	return output;
}
这里我们看到,我们首先可以创造一个画布,但是画布不能为空,需要一个打底图,我们直接使用配置Bitmap.Config.ARGB_8888配置创造一个和原图一样大小的白色图片,当然我们通过上面说的方法,可以创造一个有透明度和颜色值的图片,然后贴在画布上。这里我们看到也可以直接使用画布来设置ARGB的值,这里全是0,这时候我们可以作画了,我们绘制一个圆角矩形,绘制完成之后,我们需要设置画笔的遮罩层效果,这里是关键点,关于遮罩层有很多种选项:

android.graphics.PorterDuff.Mode.SRC:只绘制源图像
android.graphics.PorterDuff.Mode.DST:只绘制目标图像
android.graphics.PorterDuff.Mode.DST_OVER:在源图像的顶部绘制目标图像
android.graphics.PorterDuff.Mode.DST_IN:只在源图像和目标图像相交的地方绘制目标图像
android.graphics.PorterDuff.Mode.DST_OUT:只在源图像和目标图像不相交的地方绘制目标图像
android.graphics.PorterDuff.Mode.DST_ATOP:在源图像和目标图像相交的地方绘制目标图像,在不相交的地方绘制源图像
android.graphics.PorterDuff.Mode.SRC_OVER:在目标图像的顶部绘制源图像
android.graphics.PorterDuff.Mode.SRC_IN:只在源图像和目标图像相交的地方绘制源图像
android.graphics.PorterDuff.Mode.SRC_OUT:只在源图像和目标图像不相交的地方绘制源图像
android.graphics.PorterDuff.Mode.SRC_ATOP:在源图像和目标图像相交的地方绘制源图像,在不相交的地方绘制目标图像
android.graphics.PorterDuff.Mode.XOR:在源图像和目标图像重叠之外的任何地方绘制他们,而在不重叠的地方不绘制任何内容
android.graphics.PorterDuff.Mode.LIGHTEN:获得每个位置上两幅图像中最亮的像素并显示
android.graphics.PorterDuff.Mode.DARKEN:获得每个位置上两幅图像中最暗的像素并显示
android.graphics.PorterDuff.Mode.MULTIPLY:将每个位置的两个像素相乘,除以255,然后使用该值创建一个新的像素进行显示。结果颜色=顶部颜色*底部颜色/255
android.graphics.PorterDuff.Mode.SCREEN:反转每个颜色,执行相同的操作(将他们相乘并除以255),然后再次反转。结果颜色=255-(((255-顶部颜色)*(255-底部颜色))/255)

这些选项很全的,可以实现两张图片之间叠加的任何效果了。设置完打底图片的画笔遮罩层之后,那么就来绘制第二张图片,也就是原始图片,绘制完成之后,直接返回打底图片即可。

看一下效果:



看到了,这里我们选择的遮罩层选项是:Mode.XOR。就是智慧值他们两交集以外的地方,挺有意思的吧,下面我们在用Mode.SCR_IN来看看,和Mode.XOR相反,只绘制两张图片相交的地方:


好吧,这就实现了图片的圆角效果了。哈哈哈,当然还有其他遮罩的效果,大家都可以去尝试一下,也很好玩的。

知识点:

1>、手动创建一个Bitmap和Canvas

2>、了解遮罩层技术改变两张图片的叠加效果


3、画布的保存和恢复操作

这个技术,我们在自定义View的时候,用到的最多的地方,也是非常重要的一个点,他说白了,就是先在画布上绘制一个图形,然后保存一下,在绘制一个图形,然后在恢复一下,这样就可以在一个画布上绘制出不同的样式了,下面我们来看一下代码:

/**
 * 保留图层技术
 * @param canvas
 */
public static void saveCanvas(Canvas canvas){

	//首先绘制一个线条
	Paint paint = new Paint();
	paint.setColor(Color.BLUE);
	paint.setStrokeWidth(10);
	canvas.drawLine(0,0, 100,100,paint);

	//保存画布,同时设置区域l,t,r,b
	canvas.saveLayerAlpha(10, 10, 300, 300, 0x88, Canvas.ALL_SAVE_FLAG);

	//绘制圆圈
	Paint paint1 = new Paint();
	paint1.setColor(Color.RED);
	paint1.setStrokeWidth(10);
	paint1.setStyle(Paint.Style.FILL);
	canvas.drawCircle(140, 140, 100, paint1);
	canvas.restore();
}
我们看到首先,我们绘制出一个蓝色的线条,然后我们保存画布状态,我们在保存的时候,同时设置一下画布的区域和透明度,然后在绘制一个红色的圆圈,最后恢复画布,我们看一下效果:



看到了,首先红色的圆圈和蓝色的线条重叠的地方,红色图片在上面,其次是我们看到红色的圆圈有透明度的,不是全红的。这样我们就学会了保存画布和恢复画布状态操作,但是在实际的过程中我们不可能这么简单的,我们改一下代码,让画布平移一下:


这里我们使用矩阵来操作一下画布平移,然后我们看一下效果:


好了,看到了吗?圆圈移动了,其实实际上不是圆圈移动了,是画布移动了,所以要理解好画布的保存和恢复的真正含义:

每个画板Canvas创建的时候都有一个默认的图层,我们在使用save方法的时候,会在创建一个图层,然后绘制,在调用restore方法的时候,相当于两个图层的叠加操作,所以看上去是画布移动了,其实不是的,是新建了一个图层,画布不可能移动的。在说的通俗点就是:画布相当于画板,图层相当于画纸。

当然这里我们还看到了圆圈没显示全,这个就是我们上面在保存画布的时候,设置了区域,其实这个区域和透明度就是新建图层的大小和透明度,这个圆圈是绘制在新建的图层上的所以会被裁剪了。

还有一个地方需要注意的是:

我们每次如果要操作画布的时候,一定要记住一个准则:

先操作画布,在绘制图形

如果顺序反了,那么操作是没有效果的,比如上面的平移效果如果放到绘制圆圈的后面,那么就没有任何效果的。

知识点:

1>、使用画布保存技术来绘制想要的特殊效果

2>、理解了画布的平移,缩放等效果不是真正意义上的操作画布,而是新建一个图层,然后进行图层的叠加操作。

3>、使用矩阵来操作画布


4、使用矩阵实现平移,旋转,缩放效果

我们在实现View的简单的平移,旋转,缩放等功能的时候,Android中提供了很多种选择,可以使用传统动画,属性动画等。但是这里我们今天来看一下,在绘制图片的时候我们使用矩阵来实现这些效果,说道矩阵,在学习线性数学的时候,我们知道两个矩阵相乘能够实现各种变化效果,同时A*B=C,A矩阵我们理解为变化前的矩阵,B矩阵理解为变化矩阵,C矩阵理解为变化后的矩阵。当然Android中操作举证的Api不需要我们去手动的计算,而是帮我们已经封装了平移,旋转,缩放这三种功能的效果矩阵,同样我们也可以实现矩阵的手动计算,但是这里就不介绍了,因为矩阵操作还是很复杂的,感兴趣的同学可以去网上搜一下。下面我们来看一下代码:

/**
 * 使用Matrix来实现旋转图片
 * @param bitmap
 * @return
 */
public static Bitmap operateBitmap(Bitmap bitmap){
	Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
			.getHeight(), Bitmap.Config.RGB_565);
	Canvas canvas = new Canvas(output);
	Matrix matrix = new Matrix();
	matrix.postRotate(300);
	matrix.postScale(0.4f, 0.5f);
	matrix.postTranslate(100, 100);
	canvas.drawBitmap(bitmap, matrix, new Paint());
	return output;
}
这里我们依然是,先创建一个画布和打底图,然后就用矩阵来操作图片了,这里先旋转,缩放,平移,然后我们看一下效果:


看到了,图片变成这个样子了,但是这里我们看到怎么有一块是黑色的,原因是我们在创建打底图的时候设置的图片配置是:

Bitmap.Config.RGB_565

这个样式是没有透明度的,默认是黑色的。

关于Matrix矩阵操作有一个前乘和后乘的区别,因为矩阵的乘法是不支持交换律的,post开头的方法都是后乘,就是我们正常的操作效果,其中pre开头的方法是前乘,改一下代码:


看看效果:


我擦,不知道变成什么鬼了,我这里为什么要提一下前乘和后乘的区别呢?其实想说明一个问题就是:

一定不要把前乘和后乘理解为是相反的操作

如果我们想操作相反的动作,只需要把数值写成负数值即可。

知识点:

1>、学习到了矩阵操作

2>、理解了矩阵的前乘和后乘的区别


5、通过旋转,平移,缩放画布来实现动画

关于这个知识点,我们在前面自定义视图View的基础篇说到了。但是这里我们来使用选择画布的方式来实现动画效果,下面来看一下代码:

/**
 * 通过旋转画布来实现图片的旋转
 * @param canvas
 * @param bitmap
 * @param argee
 */
public void recyleRotateBitmap(Canvas canvas, Bitmap bitmap, int argee){
	//这里需要注意的是一定是先操作完画布,才能绘制,不然没效果的
	canvas.rotate(argee);
	Rect rect1 = new Rect(0,0,bitmap.getWidth(),bitmap.getWidth());
	Rect rect2 = new Rect(0,0,bitmap.getWidth(),bitmap.getHeight());
	canvas.drawBitmap(bitmap, rect1, rect2, new Paint());
	postInvalidateDelayed(200);
}
这里我们可以看到,Canvas本身也有平移,旋转,缩放的方法,可以不需要矩阵就可以实现,这里我们实现的原理很简单:就是在onDraw方法中来改变旋转角度,然后从新绘制图片,然后调用postInvalidateDelayed方法来实现画布的内容更新操作,在onDraw方法中我们的代码:


我们看一下效果:


就是图片沿着左上角的点开始旋转。

知识点:

1>、使用Canvas本身的api来操作画布


6、裁剪画布

有时候我们可能需要裁剪画布,就是把画布上已经画好的图形,我们只想要其中的一部分,那么这时候我们可以使用裁剪技术来实现,比如我们现在想把图片裁剪成不规则形状,我们看一下代码:

/**
 * 裁剪画布
 * @param canvas
 * @param bitmap
 */
public static void clipCanvas(Canvas canvas, Bitmap bitmap){

	canvas.drawColor(Color.GRAY);

	//先裁去完画布,在绘制内容

	//canvas.clipRect(0, 0, 200, 200);

	Path path = new Path();
	path.lineTo(0, 0);
	path.lineTo(400, 0);
	path.lineTo(100, 300);
	path.lineTo(0, 0);
	canvas.clipPath(path);

	Rect rect1 = new Rect(0,0,bitmap.getWidth(),bitmap.getWidth());
	Rect rect2 = new Rect(0,0,bitmap.getWidth(),bitmap.getHeight());
	canvas.drawBitmap(bitmap, rect1, rect2, new Paint());
}
这里我们绘制不规则形状使用Path来实现的,这里有一点需要注意的是,裁剪画布也算是操作画布了,所以还是要遵从一个准则:

先操作画布,在绘制图形

我们可以看一下效果:


擦,被裁成这个吊样了,我们这里还看到了,可以使用path来实现绘制不规则图形的,而且裁剪的api中也支持规则的图形裁剪,比如是:圆形,矩形等裁剪形状。

知识点:

1>、使用Path来绘制不规则图形

2>、随意裁剪图片的形状


代码下载地址:http://download.csdn.net/detail/jiangwei0910410003/9467133


四、知识点总结

到这里我们就介绍完了关于画布Canvas的一些操作,这些操作可以满足我们在日常中想要实现的效果了,下面我们就再来整理我们所学习到的知识点:

1>   我们可以使用Bitmap的getPixel方法获取图片的像素值
2>   了解到了图片像素值的表示含义和各个配置之间的差异
3>   修改图片的透明度和颜色值
4>   手动创建一个Bitmap和Canvas
5>  了解遮罩层技术改变两张图片的叠加效果
6>   使用画布保存技术来绘制想要的特殊效果
7>   理解了画布的平移,缩放等效果不是真正意义上的操作画布,而是新建一个图层,然后进行图层的叠加操作。
8>   使用矩阵来操作画布
9>   学习到了矩阵操作
10> 理解了矩阵的前乘和后乘的区别
11> 使用Canvas本身的api来操作画布
12> 使用Path来绘制不规则图形
13> 随意裁剪图片的形状


五、总结

我们这篇文章主要介绍了如何操作画布来实现我们在自定义视图View的时候想要的效果,这些api我们可以不用记住,但是这些知识点可以记住,因为我们在看到一种UI效果的时候我们可以想到有这些功能就可以了,没事多看看一些UI上的效果和特效,多想想可以怎么去实现它,这样对于我们绘制UI很有帮助,没事的时候脑补一下还是很有用途的。


更多内容:点击这里

关注微信公众号,最新Android技术实时推送


我们今天的关于canvas的使用方法canvas的使用步骤的分享已经告一段落,感谢您的关注,如果您想了解更多关于Android 中View.onDraw(Canvas canvas)的使用方法、android-canvas(一) scale(缩放)的使用、Android中Canvas的常用方法总结、Android中自定义视图View之---进阶篇(Canvas的使用)的相关信息,请在本站查询。

本文标签: