您的位置:首页 > 移动开发 > Android开发

自定义View起步:Canvas之绘制图片

2017-04-12 22:01 302 查看
          在前面的章节中,我们已经介绍了Canvas的一些基本操作,今天我们继续讲解,Canvas类的用法,可见这个类在自定义View中是多么的重要。今天我们来着重介绍一下如何绘制图片和文字。在这一章节学习之后我们基本上对于一些简单的自定义View就可以搞定了。但是这仅仅是刚刚开始,我还会继续带领大家深入的学习下去,做出更多更炫酷的自定义控件出来。

 第一、drawPicture绘制图片



上面是官网中提供的此类的方法,beginRecording()意思为开始录制,什么意思呢。看一段官网的解释再说:To record a picture, call beginRecording() and then draw into the Canvas that is returned. Nothing we appear on screen, but all of the draw commands (e.g.
drawRect(Rect, Paint)
) will be recorded. To stop recording, call endRecording(). After
endRecording() the Canvas that was returned must no longer be used, and nothing should be drawn into it.意思是此方法开始记录一幅画,就是canvas的操作。直到endRecording()方法的调用,结束录制。注意:endRecording()调用之后此画布必须保证不再使用。什么意思呢,我们可以通俗的理解为,此方法的操作是可以记录一个画布,然后重复的使用,每次使用都是和上一次一样的。是不是这样可以大大减少我们的内存开支,只要首次加载的时候绘制一遍,之后每次都使用记录的内容就可以。后面是getHeight和getWidth两个方法,获取宽和高很简单就不说了。最后一个输出流,可以看到在API18之后已经废弃了,就先不考虑了。

 第二、Picture的使用步骤

1、初始化对象

//第一步创建Picture
private Picture mPicture = new Picture();

2、录制画布的操作

//开始录制绘制的内容
private void recording(){
//开始录制图片,返回一个canvas,此canvas的所有操作都将会被录制。
Canvas canvas = mPicture.beginRecording(500,500);
//创建一个画笔
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL);

//位移画布中心点坐标一段距离
canvas.translate(500,500);
//绘制一个圆
canvas.drawCircle(0,0,300,paint);
//录制结束
mPicture.endRecording();
}

3、调用

public CustomPictureText(Context context, AttributeSet attrs) {
super(context, attrs);
// 调用录制
recording();

}

4、开始绘制

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

}

5、结果如图



7、绘制的方法有很多,以上的方法在低版本中可能会影响Canvas的状态。下面我们来介绍Canvas为我们提供的绘制方法。来比较一下有什么差别

public void drawPicture (Picture picture)

public void drawPicture (Picture picture, Rect dst)

public void drawPicture (Picture picture, RectF dst)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPicture(mPicture,new RectF(0,0,mPicture.getWidth(),200));

}


效果如图:



如图所示我们的圆变成了椭圆,是什么造成的呢,这里我们的绘制的时候传入了一个矩形,这个矩形就是用来压缩我们的begin开始录制的时候返回的画布的,当时我们设置为500,500.可以看到我们这里的方法是宽保持不变,高度变为原来的二分之一一,就把原来的圆压缩为现在的椭圆了。

8.将Picture包装成为PictureDrawable,使用PictureDrawable的draw方法绘制。

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//包装成drawable
PictureDrawable drawable = new PictureDrawable(mPicture);
//设置绘制的区域
drawable.setBounds(0,0,500,mPicture.getHeight());
drawable.draw(canvas);

}

注意这里的setBounds方法,来设置的是绘制区域,设置的是现在onDraw方法里边的画布,而不是我们picture的画布。设置的区域为左边左上角0,0.到500,图片高度。这里将会展示出来一个四分之一的圆。



第三、drawBitmap绘制图片

一提到Bitmap可能大多数的小伙伴都会有一种莫名其妙的不知所措,什么内存溢出了,内存泄漏了,好像很多都是和Bitmap有关的,但是今天我们不会深入的去研究这里边的原理,今天我们先介绍一下,使用drawBitmap来绘制我们的图片资源。既然是绘制Bitmap那么我们肯定需要先获取到Bitmap才对。获取Bitmap我们使用BitmapFactory来获取,他可以获取,手机存储卡,资源文件,网络图片转换为我们使用的Bitmap。其实还有其他的两种方法,但是今天我们就先介绍BitmaoFactory这个最常用的。

1、通过资源文件获取Bitmap(drawable/mipmap/raw)

Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.dafenqi);


2、通过assets获取

//从assets中获取资源文件
Bitmap bitmap = null;
try {
InputStream inputStream = mContext.getAssets().open("dafenqi.png");
bitmap = BitmapFactory.decodeStream(inputStream);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}


3、通过内存卡

Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/bitmap.png");
4、通过网络

// 此处省略了获取网络输入流的代码
Bitmap bitmap = BitmapFactory.decodeStream(is);
is.close();

5、下面我们将itmap绘制到我们的界面上



第一种方法中后两个参数(matrix, 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,200);

// 绘制图片
canvas.drawBitmap(bitmap,src,dst,null);




详解:

上面是以绘制该图为例,用src指定了图片绘制部分的区域,即下图中红色方框标注的区域。



然后用dst指定了绘制在屏幕上的绘制,即下图中蓝色方框标注的区域,图片宽高会根据指定的区域自动进行缩放。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息