1.绘制图片
绘制有两种方法,drawPicture(矢量图) 和 drawBitmap(位图)
(1)drawPicture
使用Picture前请关闭硬件加速,以免引起不必要的问题!
在AndroidMenifest文件中application节点下添上 android:hardwareAccelerated=”false”以关闭整个应用的硬件加速。
Picture的相关方法
beginRecording 和 endRecording 是成对使用的,一个开始录制,一个是结束录制,两者之间的操作将会存储在Picture中。
Canvas操作用Picture存储起来,录制的内容是不会直接显示在屏幕上的,只是存储起来了而已。
// 1.创建Pictureprivate Picture mPicture = new Picture();---------------------------------------------------------------// 2.录制内容方法private void recording() {// 开始录制 (接收返回值Canvas)Canvas canvas = mPicture.beginRecording(500, 500);// 创建一个画笔Paint paint = new Paint();paint.setColor(Color.BLUE);paint.setStyle(Paint.Style.FILL);// 在Canvas中具体操作// 位移canvas.translate(250,250);// 绘制一个圆canvas.drawCircle(0,0,100,paint);mPicture.endRecording();}---------------------------------------------------------------// 3.在使用前调用(我在构造函数中调用了)public Canvas3(Context context, AttributeSet attrs) {super(context, attrs);recording(); // 调用录制}
想要将Picture中的内容显示出来就需要手动调用播放绘制,将Picture中的内容绘制出来可以有以下几种方法:
以上几种方法主要区别:
1.使用Picture提供的draw方法绘制:
// 将Picture中的内容绘制在Canvas上mPicture.draw(canvas);
这种方法在比较低版本的系统上绘制后可能会影响Canvas状态,所以这种方法一般不会使用。
2.使用Canvas提供的drawPicture方法绘制
drawPicture有三种方法:
public void drawPicture (Picture picture)public void drawPicture (Picture picture, Rect dst)public void drawPicture (Picture picture, RectF dst)
和使用Picture的draw方法不同,Canvas的drawPicture不会影响Canvas状态。
简单示例:
canvas.drawPicture(mPicture,new RectF(0,0,mPicture.getWidth(),200));
绘制的内容会根据选区进行了缩放。
3.将Picture包装成为PictureDrawable,使用PictureDrawable的draw方法绘制。
// 包装成为DrawablePictureDrawable drawable = new PictureDrawable(mPicture);// 设置绘制区域 -- 注意此处所绘制的实际内容不会缩放drawable.setBounds(0,0,250,mPicture.getHeight());// 绘制drawable.draw(canvas);
此处setBounds是设置在画布上的绘制区域,并非根据该区域进行缩放,也不是剪裁Picture,每次都从Picture的左上角开始绘制。在使用Picture之前请关闭硬件加速,以免引起不必要的问题
(2)drawBitmap
通过BitmapFactory从不同位置获取Bitmap:
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();
既然已经获得到了Bitmap,那么就开始本文的重点了,将Bitmap绘制到画布上。
绘制Bitmap:
依照惯例先预览一下drawBitmap的常用方法:
// 第一种public void drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint)// 第二种public void drawBitmap (Bitmap bitmap, float left, float top, Paint paint)// 第三种public void drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint)public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint)
第一种方法中后两个参数(matrix, paint)是在绘制的时候对图片进行一些改变,如果只是需要将图片内容绘制出来只需要如下操作就可以了:
canvas.drawBitmap(bitmap,new Matrix(),new Paint());
图片左上角位置默认为坐标原点。
第二种方法就是在绘制时指定了图片左上角的坐标(距离坐标原点的距离):
注意:此处指定的是与坐标原点的距离,并非是与屏幕顶部和左侧的距离, 虽然默认状态下两者是重合的,但是也请注意分别两者的不同。
canvas.drawBitmap(bitmap,200,500,new Paint());
第三种方法,多了两个矩形区域(src,dst)
// 将画布坐标系移动到画布中央canvas.translate(mWidth/2,mHeight/2);// 指定图片绘制区域(左上角的四分之一)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指定了图片绘制部分的区域,dst指定了绘制在屏幕上的绘制,图片宽高会根据指定的区域自动进行缩放。
2.绘制文字
常用方法如下:
// 第一类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)
绘制文字部分大致可以分为三类:
第一类只能指定文本基线位置(基线x默认在字符串左侧,基线y默认在字符串下方)。
第二类可以分别指定每个文字的位置。
第三类是指定一个路径,根据路径绘制文字。
绘制文字也是需要画笔的,而且文字的大小,颜色,字体,对齐方式都是由画笔控制的。
Paint文本相关常用方法表
为了绘制文本,我们先创建一个文本画笔:
Paint textPaint = new Paint();// 创建画笔textPaint.setColor(Color.BLACK); // 设置颜色textPaint.setStyle(Paint.Style.FILL); // 设置样式textPaint.setTextSize(50); // 设置字体大小
第一类(drawText)
第一类可以指定文本开始的位置,可以截取文本中部分内容进行绘制。
其中x,y两个参数是指定文本绘制两个基线,示例:
// 文本(要绘制的内容)String str = "ABCDEFG";// 参数分别为 (文本 基线x 基线y 画笔)canvas.drawText(str,200,500,textPaint);
除了能指定绘制文本的起始位置,还能只取出文本中的一部分内容进行绘制。
截取文本中的一部分,对于String和CharSequence来说只指定字符串下标start和end位置(注意:0<= start < end < str.length())
假设我我们指定star为1,end为3,那么最终截取的字符串就是”BC”。
使用start和end指定的区间是前闭后开的,即包含start指定的下标,而不包含end指定的下标,故[1,3)最后获取到的下标只有 下标1 和 下标2 的字符,就是”BC”.
// 文本(要绘制的内容)String str = "ABCDEFG";// 参数分别为 (字符串 开始截取位置 结束截取位置 基线x 基线y 画笔)canvas.drawText(str,1,3,200,500,textPaint);
另外,对于字符数组char[]我们截取字符串使用起始位置(index)和长度(count)来确定。
同样,我们指定index为1,count为3,那么最终截取到的字符串是”BCD”.
其实就是从下标位置为1处向后数3位就是截取到的字符串,示例:
// 字符数组(要绘制的内容)char[] chars = "ABCDEFG".toCharArray();// 参数为 (字符数组 起始坐标 截取长度 基线x 基线y 画笔)canvas.drawText(chars,1,3,200,500,textPaint);
第二类(drawPosText)
通过和第一类比较,我们可以发现,第二类中没有指定x,y坐标的参数,而是出现了这样一个参数float[] pos。
pos的浮点型数组就是指定坐标的,可以给每个字符都指定一个位置。
String str = "SLOOP";canvas.drawPosText(str,new float[]{100,100, // 第一个字符位置200,200, // 第二个字符位置300,300, // ...400,400,500,500},textPaint);
关于第二类的第二种方法:
public void drawPosText (char[] text, int index, int count, float[] pos, Paint paint)
就是从字符数组中切出来一段进行绘制