一. 前言

绘制图片分为:绘制矢量图(drawPicture)和 绘制位图(drawBitmap)。

二. 绘制矢量图

1. 作用

绘制矢量图的内容,即绘制存储在矢量图里某个时刻Canvas绘制内容的操作。

2. 应用场景

① 相比于再次调用各种绘图API,使用Picture能节省操作 & 时间。

② 如果不手动调用,录制的内容不会显示在屏幕上,只是存储起来。

3. 使用步骤

1
2
3
4
5
//开始录制
public Canvas beginRecording(int width, int height)

//结束录制
public void endRecording()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 步骤1:创建Picture对象
Picture mPicture = new Picture();

// 步骤2:开始录制 返回一个Canvas
mPicture.beginRecording(int width, int height);

// 步骤3:绘制内容 or 操作Canvas
canvas.drawCircle(500,500,400,mPaint);
// ...(一系列操作)

// 步骤4:结束录制
mPicture.endRecording ();

// 步骤5:某个时刻将存储在Picture的绘制内容绘制出来
mPicture.draw (Canvas canvas);

4. 调用录制好的Picture的三种方式

① Picture的draw方法

1
2
3
4
5
6
7
8
9
// 在复写的onDraw里
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);

// 将录制的内容显示在当前画布里
// 注:此方法绘制后可能会影响Canvas状态,不建议使用
mPicture.draw(canvas);
}

② Canvas的drawPicture提供了三种方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 方法1
public void drawPicture (Picture picture)
// 方法2
// Rect dst代表显示的区域,若区域小于图形,绘制的内容根据选区进行缩放
public void drawPicture (Picture picture, Rect dst)
// 方法3
public void drawPicture (Picture picture, RectF dst)

@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);

// 实例1:将录制的内容显示(区域刚好布满图形)
canvas.drawPicture(mPicture, new RectF(0, 0, mPicture.getWidth(), mPicture.getHeight()));

// 实例2:将录制的内容显示在当前画布上(区域小于图形)
canvas.drawPicture(mPicture, new RectF(0, 0, mPicture.getWidth(), 200));
}

③ PictureDrawable的draw方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);

// 将录制的内容显示出来
// 将Picture包装成为Drawable
PictureDrawable drawable = new PictureDrawable(mPicture);

// 设置在画布上的绘制区域(类似drawPicture (Picture picture, Rect dst)的Rect dst参数)
// 每次都从Picture的左上角开始绘制
// 并非根据该区域进行缩放,也不是剪裁Picture。

// 实例1:将录制的内容显示(区域刚好布满图形)
drawable.setBounds(0, 0,mPicture.getWidth(), mPicture.getHeight());
// 绘制
drawable.draw(canvas);


// 实例2:将录制的内容显示在当前画布上(区域小于图形)
drawable.setBounds(0, 0,250, mPicture.getHeight());
// 绘制
drawable.draw(canvas);
}

④ 总结

三. 绘制位图

1. 作用

将已有的图片转换为位图(Bitmap),最后再绘制到Canvas上。

2. 获取bitmap的三种方式

第一种方式排除,第二种方式虽然满足要求,但是一般不推荐使用,一般使用第三种。

3. BitmapFactory获取Bitmap的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 共3个位置:资源文件、内存卡、网络

// 位置1:资源文件(drawable/mipmap/raw)
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),R.raw.bitmap);

// 位置2:资源文件(assets)
Bitmap bitmap = null;
try {
InputStream is = mContext.getAssets().open("bitmap.png");
bitmap = BitmapFactory.decodeStream(is);
is.close();
} catch (IOException e) {
e.printStackTrace();
}

// 位置3:内存卡文件
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/bitmap.png");

// 位置4:网络文件:
// 省略了获取网络输入流的代码
Bitmap bitmap = BitmapFactory.decodeStream(is);
is.close();

4. 绘制Bitmap的四种方式

1
2
3
4
5
6
7
8
9
10
11
// 方法1
public void drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint)

// 方法2
public void drawBitmap (Bitmap bitmap, float left, float top, Paint paint)

// 方法3
public void drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint)

// 方法4
public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint)

① 方法1

1
2
3
4
5
//参数matrix, paint是在绘制时对图片进行一些改变
public void drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint)

//简单的绘制出来
canvas.drawBitmap(bitmap,new Matrix(),new Paint());

关于利用Matrix对图片的操作可以参考:Bitmap的简单使用

② 方法2

1
2
3
4
5
//参数 left、top 指定了图片左上角的坐标(距离坐标原点的距离):
public void drawBitmap (Bitmap bitmap, float left, float top, Paint paint)

//简单的绘制出来
canvas.drawBitmap(bitmap,300,400,new Paint());

③ 方法3

1
2
3
4
5
6
7
8
9
10
11
12
13
//参数(src,dst) = 两个矩形区域
//Rect src:指定需要绘制图片的区域(即要绘制图片的哪一部分)
//Rect dst 或RectF dst:指定图片在屏幕上显示(绘制)的区域
//特别注意的是:如果src规定绘制图片的区域大于dst指定显示的区域的话,那么图片的大小会被缩放。
public void drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint)

//指定图片绘制区域
//仅绘制图片的二分之一
Rect src = new Rect(0,0,bitmap.getWidth()/2,bitmap.getHeight());
//指定图片在屏幕上显示的区域
Rect dst = new Rect(100,100,250,250);
//简单的绘制图片
canvas.drawBitmap(bitmap,src,dst,null);

应用场景:

① 素材管理

将素材都放在一个图,那么按需绘制会便于管理

② 实现动态效果

一个资源文件,然后逐渐描绘就可以达到动态效果。