自定义View-第五步:绘制图片

前言

根据Gcssloop所学习的自定义View整理与笔记。

准备

** 禁用GPU硬件加速**

  1. 在AndroidManifest.xml文件为application标签添加如下的属性即可为整个应用程序开启/关闭硬件加速:
<application android:hardwareAccelerated="false" ...>
  1. 在Activity 标签下使用 hardwareAccelerated 属性开启或关闭硬件加速:
<activity android:hardwareAccelerated="false" />  
  1. 在Window 层级使用如下代码开启硬件加速:(Window层级不支持关闭硬件加速)
getWindow().setFlags(  
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,  
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); 
  1. View 级别如下关闭硬件加速:(view 层级上不支持开启硬件加速)
setLayerType(View.LAYER_TYPE_SOFTWARE, null);

或者使用android:layerType=”software”来关闭硬件加速

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:orientation="vertical"  
    android:paddingLeft="2dp"  
    android:layerType="software"  
    android:paddingRight="2dp" >  

一、drawPicture:录制Canvas中绘制的内容

** 使用Picture前请关闭硬件加速,以免引起不必要的问题!**
详情请进入这里->Android的硬件加速及可能导致的问题

首先,了解一下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中

现在开始使用啦♪(*)

  1. 第一步:使用Picture录制内容
//录制内容
private void recording() {
    Canvas canvas = picture.beginRecording(500, 500);
    canvas.translate(250, 250);
    canvas.drawCircle(0, 0, 100, paint);
    picture.endRecording();
}
  • 第二步:将录制的内容显示出来(三种方式)
    1. 使用Picture提供的draw方法绘制。
// 将Picture中的内容绘制在Canvas上,一般不使用 
       picture.draw(canvas);

效果图为:


  1. 使用Canvas提供的drawPicture方法绘制,会缩放。
public void drawPicture (Picture picture)
public void drawPicture (Picture picture, Rect dst)
public void drawPicture (Picture picture, RectF dst)

举个栗子:

        paint.setColor(Color.RED);
        canvas.drawRect(0, 0, 100, 200, paint);
        paint.setColor(Color.BLACK);
        canvas.drawPicture(picture, new RectF(0, 0, 100, 200));

效果图为:


**绘制的内容根据选区进行了缩放**
  1. 将Picture包装成为PictureDrawable,使用PictureDrawable的draw方法绘制,不会缩放。
  paint.setColor(Color.RED);
  canvas.drawRect(0, 0, 250, picture.getHeight(), paint);
 paint.setColor(Color.BLACK);
 // 包装成为Drawable
 PictureDrawable drawable = new PictureDrawable(picture);
// 设置绘制区域 -- 注意此处所绘制的实际内容不会缩放
drawable.setBounds(0, 0, 250, picture.getHeight());
// 绘制
drawable.draw(canvas);

效果图:


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

ps:三种方法的主要区别:
是否对Canvas有影响: 1有影响;2,3不影响
此处指绘制完成后是否会影响Canvas的状态(Matrix clip等)
可操作性强弱: 1可操作性较弱;2,3可操作性较强
此处的可操作性可以简单理解为对绘制结果可控程度。

接下来上代码喽

二、drawBitmap

看到bitmap有点怕怕的,哈哈,内存泄漏的大麻烦啊,GcsSloop简单的讲解了一下,那我也跟着简单的学一下讲一下吧,嘿嘿
1.第一步:通过BitmapFactory从不同位置获取Bitmap

//资源文件(drawable/mipmap/raw)中获取
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),R.raw.bitmap);
//资源文件(assets)
Bitmap bitmap=null;
try {
 InputStream is = mContext.getAssets().open("bitmap.png");
 bitmap = BitmapFactory.decodeStream(is);
 is.close();
} catch (IOException e) {
 e.printStackTrace();
}
//内存卡文件
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/bitmap.png");
//网络文件
Bitmap bitmap = BitmapFactory.decodeStream(is);
is.close();

2.第二步:绘制Bitmap

  1. 第一种
/** * Draw the bitmap using the specified matrix. * 
* @param bitmap The bitmap to draw
 * @param matrix The matrix used to transform the bitmap when it is drawn
 * @param paint  May be null. The paint used to draw the bitmap
 */
public void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint) {
    nativeDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(),            
paint != null ? paint.getNativeInstance() : 0);
}

demo:

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

2.第二种

 /** 
* @param bitmap The bitmap to be drawn
 * @param left   The position of the left side of the bitmap being drawn 
* @param top    The position of the top side of the bitmap being drawn 
* @param paint  The paint used to draw the bitmap (may be null) 
*/
public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) {
    throwIfCannotDraw(bitmap);
    native_drawBitmap(mNativeCanvasWrapper, bitmap, left, top, 
           paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity, bitmap.mDensity);
}

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

demo:

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

3.第三种

 /* 
@param bitmap The bitmap to be drawn 
* @param src    May be null. The subset of the bitmap to be drawn
 * @param dst    The rectangle that the bitmap will be scaled/translated to fit into
 * @param paint  May be null. The paint used to draw the bitmap
 */
public void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull Rect dst,        @Nullable Paint paint);

demo:

// 将画布坐标系移动到画布中央
canvas.translate(200, 200);
// 指定图片绘制区域(左上角的四分之一)
Rect src = new Rect(0, 0, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
// 指定图片在屏幕上显示的区域
Rect dst = new Rect(0, 0, 100, 200);
// 绘制图片
canvas.drawBitmap(bitmap, src, dst, null);
效果
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,175评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,674评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,151评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,597评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,505评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,969评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,455评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,118评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,227评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,213评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,214评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,928评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,512评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,616评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,848评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,228评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,772评论 2 339

推荐阅读更多精彩内容