Android 自定义View探索——图片

绘制图片

绘制有两种方法,drawPicture(矢量图) 和 drawBitmap(位图),接下来我们一一了解。

drawPicture

使用Picture前请关闭硬件加速,以免引起不必要的问题,因此在AndroidMenifest文件中application节点下添上 android:hardwareAccelerated=”false”以关闭整个应用的硬件加速。

我们把Canvas绘制点,线,矩形等诸多操作用Picture录制下来,下次需要的时候拿来就能用,使用Picture相比于再次调用绘图API,开销是比较小的,也就是说对于重复的操作可以更加省时省力。

可以把Picture看作是一个录制Canvas操作的录像机。

相关方法
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中内容写出到输出流中

很明显,beginRecording 和 endRecording 是成对使用的,一个开始录制,一个是结束录制,两者之间的操作将会存储在Picture中。

来写个Demo试试

// 1.创建Picture
private 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虽然方法就那么几个,但是具体使用起来还是分很多情况的,由于录制的内容不会直接显示,就像存储的视频不点击播放不会自动播放一样,同样,想要将Picture中的内容显示出来就需要手动调用播放(绘制),将Picture中的内容绘制出来可以有以下几种方法:

  1. 使用Picture提供的draw方法绘制。
  2. 使用Canvas提供的drawPicture方法绘制。
  3. 将Picture包装成为PictureDrawable,使用PictureDrawable的draw方法绘制。

下面来逐一分析

  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));

这种方法制定了绘制区域,因此会产生缩放等效果

  1. 将Picture包装成为PictureDrawable,使用PictureDrawable的draw方法绘制。
// 包装成为Drawable
PictureDrawable drawable = new PictureDrawable(mPicture);
// 设置绘制区域 -- 注意此处所绘制的实际内容不会缩放
drawable.setBounds(0,0,250,mPicture.getHeight());
// 绘制
drawable.draw(canvas);

此处setBounds是设置在画布上的绘制区域,并非根据该区域进行缩放,也不是剪裁Picture,每次都从Picture的左上角开始绘制。

drawBitmap

依照惯例先预览一下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)是在绘制的时候对图片进行一些改变,如果只是需要将图片内容绘制出来只需要如下操作就可以了:

PS:图片左上角位置默认为坐标原点。

canvas.drawBitmap(bitmap,new Matrix(),new Paint());

第二种方法就是在绘制时指定了图片左上角的坐标(距离坐标原点的距离):

注意:此处指定的是与坐标原点的距离,并非是与屏幕顶部和左侧的距离, 虽然默认状态下两者是重合的,但是也请注意分别两者的不同。

canvas.drawBitmap(bitmap,200,500,new Paint());

第三种方法比较有意思,上面多了两个矩形区域(src,dst),这两个矩形选区是干什么用的?

Rect src 指定绘制图片的区域
Rect dst 或RectF 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);

你可能感兴趣的:(Android 自定义View探索——图片)