绘制图片
绘制有两种方法,drawPicture(矢量图) 和 drawBitmap(位图)
drawPicture
picture:翻译过来就是图片的意思。但是在这里你可以将它理解成录像机一样的功能。因为它是将一系列绘制操作记录下来,保存成一个对象,在你想绘制的时候,拿着这个对象进行一些操作就可以讲之前保存的操作绘制出来。
也可以理解成将一系列的绘制操作,绘制到一张图片上,当你想要讲这张图片展示的时候,可以随便复制,展示。
Picture是一个类,下边是他的一些方法:
相关方法 | 简介 |
---|---|
public int getWidth () | 获取宽度 |
public int getHeight () | 获取高度 |
public Canvas beginRecording (int width, int height) | 开始录制 (返回一个Canvas,在Canvas中所有的绘制都会存储在Picture中) |
public void endRecording () | 结束录制 |
public void draw (Canvas canvas) | 将Picture中内容绘制到Canvas中 |
public static Picture createFromStream (InputStream stream) | (已废弃)通过输入流创建一个Picture |
public void writeToStream (OutputStream stream) | (已废弃)将Picture中内容写出到输出流中 |
上边的方法解释的很清楚,主要流程:
- 先实例化一个picture对象;
- 再调用beginRecording(int width,int height)方法得到canvas,设定绘制区域,获得画板,开始绘制操作;
- 使用canvas对象进行具体操作;
- 绘制完成,调用endRecording();结束绘制。这个时候所有绘制的操作都保存在picture对象里边。
- 在想要调用这些绘制的时候,使用picture的draw(Canvas canvas)方法进行展示。
具体看代码:
//先实例化picture对象
Picture mPicture = new Picture();
...
private void recording() {
Canvas canvas = mPicture.beginRecording(500, 500);
canvas.translate(250, 250);
canvas.drawCircle(0, 0, 100, paint);
canvas.rotate(90);
mPicture.endRecording();
}
...
private void initView() {
//在view初始化的时候调用录制
recording();
}
上边的操作只是录制操作,录制的内容不会自动展示到手机上,就像录制的视频不点击播放也不会自己自定播放一样,只是在存储可中存着一样。所以我们需要手动调用这些录制的操作。下边有三种方法可以将录制的内容展示出来。
序号 | 简介 |
---|---|
1 | 使用Picture提供的draw方法绘制。 |
2 | 使用Canvas提供的drawPicture方法绘制。 |
3 | 将Picture包装成为PictureDrawable,使用PictureDrawable的draw方法绘制。 |
上边三种方法不建议使用第一种,后边两种根据具体需求使用。
下边介绍一下三种方法的用法:
第一种绘制方法:使用Picture提供的draw方法绘制
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPicture.draw(canvas);
}
第二种绘制方法:使用Canvas提供的drawPicture方法绘制
drawPicture(Picture picture);
drawPicture(Picture picture,Rect rect);
drawPicture(Picture picture,RectF rectf);
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPicture(mPicture,new Rect(0,0,300,400));
}
后边两种重载方法是指定绘制的区域,在指定区域中调用之前录制的绘制图片,如果指定区域尺寸比之前绘制的图片小的话,会等比例缩小;如果指定区域尺寸比之前绘制的图片大的话,会等比例放大。
第三种绘制方法:将Picture包装成为PictureDrawable,使用PictureDrawable的draw方法绘制
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
PictureDrawable pictureDrawable = new PictureDrawable(mPicture);
//设置绘制区域,此处绘制的实际内容不会缩放 如果不设置这个绘制区域,将不会进行绘制。默认绘制区域为0
pictureDrawable.setBounds(0, 0, 300, 300);
pictureDrawable.draw(canvas);
}
这里setBounds()设置的绘制区域,与上边一种方法不同。不会根据区域缩放picture,而是每次都会左上角点开始绘制,绘制整个区域的大小。相当于在电视上覆盖一个区域,只能看到这个区域中的图像,图像被没有被剪裁,也没有缩放。
注意:在使用Picture之前请关闭硬件加速,以免引起不必要的问题
drawBitmap
Bitmap是一个图片的对象,这里的图片是真正的图片,不是录制之类的东西。
bitmap是一系列像素点的数据,是一张图片的数据载体。
drawBitmap();是canvas里边的方法,作用就是绘制图片,比如你的自拍,等等。
// 第一种 这种方法在绘制的时候很根据matrix和paint对图片进行一些改变,如果只是简单的绘制下来,后边两个参数直接使用简单的对象就行
public void drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint)
// 第二种 这种方法后边两个参数的作用就是指定图片绘制的位置距离原点的距离
public void drawBitmap (Bitmap bitmap, float left, float top, Paint paint)
// 第三种 src表示图片的区域 dst表示在屏幕上绘制的区域
public void drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint)
public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint)
第一种:drawBitmap (bitmap, matrix, paint)
简单绘制,没有对里边的Matrix和Paint 进行操作。
canvas.drawBitmap(mBitmap,new Matrix,new Paint);
图片的左上角默认为左边原点
第二种:drawBitmap(bitmap,left,top,paint)
canvas.drawBitmap(mBitmap, 200,300, new Paint());
这里边的距离是距坐标原点的距离
第三种:drawBitmap ( bitmap, src, dst, paint)
名称 | 作用 |
---|---|
Rect src | 指定绘制图片的区域 |
Rect dst 或RectF dst | 指定图片在屏幕上显示(绘制)的区域 |
// 指定图片绘制区域(左上角的四分之一)
Rect src = new Rect(0,0,bitmap.getWidth()/2,bitmap.getHeight()/2);
// 指定图片在屏幕上显示的区域
Rect dst = new Rect(0,0,200,400);
// 绘制图片
canvas.drawBitmap(bitmap,src,dst,null);
上边代码里边的src其实是这张卡通图片的左上角的1/4;dst是屏幕上的一块区域,大概长200,宽400。
我们看到绘制出来的效果确实只有原来图片的一部分,可是有点缩放了。这是因为图片1/4的区域比dst要大,但是还要将这src绘制到dst内部,就要进行缩放了。
src: 指定要绘制的图片的区域
dst:屏幕绘制区域
这种方法还可以进行一些炫酷动画效果的制作,也就是依次绘制一张图片的不同位置。具体操作参照:安卓自定义View进阶-Canvas之图片文字
文字绘制
绘制文字的几种方法:
// 第一类
public void drawText (String text, float x, float y, Paint paint)
public void drawText (String text, int start, int end, float x, float y, Paint paint)
public void drawText (CharSequence text, int start, int end, float x, float y, Paint paint)
public void drawText (char[] text, int index, int count, float x, float y, Paint paint)
// 第二类
public void drawPosText (String text, float[] pos, Paint paint)
public void drawPosText (char[] text, int index, int count, float[] pos, Paint paint)
// 第三类
public void drawTextOnPath (String text, Path path, float hOffset, float vOffset, Paint paint)
public void drawTextOnPath (char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)
这里只讲第一种,第二种不经常使用,看一下有个印象,第三种涉及到path,后边再讲。
我先总结一下第一种方法:其中x,y两个参数是文字左下角离坐标原点的距离;文字的左边为和下边为基线;当第一个参数为string类型或者CharSequence时,后边两个参数,start和end表示text字符串的两个位置;当地一个参数为char[]时,后边两个参数index和count表示text的index和index+count两个位置。
下边看一下具体操作:
指定文本开始的位置
// 文本(要绘制的内容)
String str = "ABCDEFG";
// 参数分别为 (文本 基线x 基线y 画笔)
canvas.drawText(str,200,500,textPaint);
图中文字下边的红线就是两条基线其中之一
String CharSequence两种类型的绘制
// 文本(要绘制的内容)
String str = "ABCDEFG";
// 参数分别为 (字符串 开始截取位置 结束截取位置 基线x 基线y 画笔)
canvas.drawText(str,1,3,200,500,textPaint);
1和3表示从字符串中截取[1,3)
Char[] 字符数组的绘制
// 字符数组(要绘制的内容)
char[] chars = "ABCDEFG".toCharArray();
// 参数为 (字符数组 起始坐标 截取长度 基线x 基线y 画笔)
canvas.drawText(chars,1,3,200,500,textPaint);
这里边的1和3表示从字符数组中截取[1,1+3)