Android——Bitmap.decodeResource(Resources src, int id)和Bitmap.creatBitmap(...)

本文详细介绍了在Android中使用API进行绘图的过程,并解释了如何创建可编辑的Bitmap以供Canvas类绘制。文中还强调了不可直接在immutable的Bitmap上绘图,并提供了创建mutable Bitmap的方法。

  大家都知道用Android的API画图比JAVA麻烦得多,其实也不是太多,稍微抱怨一下下。

  下面先把Android画图的逻辑捋一下:首先,先考虑图片要画在哪,一般是imageView这控件。imageView的作用呢是用来装一张图片的,因此需要用到位图Bitmap这个类。然后

考虑用什么工具对Bitmap进行操作(也就是在上面绘画)?一般会用到canvas和paint这两个类。canvas是画布,提供的作图的方法,譬如画一个圆canvas.drawOval()还是画一个

矩形canvas.drawRect()。当然光有方法不行还要有画笔paint来把这个圆画出来,因此用canvas画图的时候还要在最后加入paint这个参数。

  当然,上面说的都是废话,今天主要是讨论创建canvas类时,new canvas(Bitmap bmp),bmp是否可以随便给?先看看canvas的实现:

public Canvas(Bitmap bitmap) {
        if (!bitmap.isMutable()) {
            throw new IllegalStateException("Immutable bitmap passed to Canvas constructor");
        }
        throwIfRecycled(bitmap);
        mNativeCanvas = initRaster(bitmap.ni());
        mFinalizer = new CanvasFinalizer(mNativeCanvas);
        mBitmap = bitmap;
        mDensity = bitmap.mDensity;
    }
  倒数面5行由于看不懂就不管了,不过我从前面这个if判断就知道Bitmap的Mutable若为false,即不可修改的话就会报错,这说明画布不能在immutable的位图上画图。

  而通过直接加载资源得到的位图一般都是immutable的,即Bitmap.decodeResource()。所以不能直接在刚加载得到的位图上作图,必须先将该位图画在另一位图上,然后才开始

作图。就举一个例子:

 /**
     * Returns a mutable bitmap with the specified width and height.  Its
     * initial density is as per {@link #getDensity}.
     *
     * @param width    The width of the bitmap
     * @param height   The height of the bitmap
     * @param config   The bitmap config to create.
     * @throws IllegalArgumentException if the width or height are <= 0
     */
    public static Bitmap createBitmap(int width, int height, Config config) {
        return createBitmap(width, height, config, true);
    }
看注释就知道这个调用会返回一个mutable的Bitmap,即canvas可以在上面作图。




package com.example.bulbpage.bulbcontrol import android.content.Context import android.graphics.* import android.util.AttributeSet import android.view.View import com.example.bulbpage.R class LampProgressView(context: Context, attrs: AttributeSet) : View(context, attrs) { private var progress = 0f // 0.0f ~ 1.0f private val paint = Paint() private var bitmap: Bitmap? = null init { // 加载灯泡图片资源 bitmap = BitmapFactory.decodeResource(resources, R.drawable.bulbonbody) } // 设置进度(外部调用) fun setProgress(progress: Float) { this.progress = progress.coerceIn(0f..1f) invalidate() } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) val bitmap = bitmap ?: return // 计算显示区域(从下往上) val showHeight = (bitmap.height * progress).toInt() val srcRect = Rect( 0, bitmap.height - showHeight, bitmap.width, bitmap.height ) // 绘制目标区域(适配 View 尺寸) val dstRect = Rect(0, 0, width, height) // 裁剪绘制 canvas.drawBitmap(bitmap, srcRect, dstRect, paint) } } package com.example.bulbpage.bulbcontrol import android.content.Context import android.graphics.* import android.util.AttributeSet import android.view.View import com.example.bulbpage.R class LampProgressView(context: Context, attrs: AttributeSet) : View(context, attrs) { private var progress = 0f // 0.0f ~ 1.0f private val paint = Paint() private var bitmap: Bitmap? = null init { // 加载灯泡图片资源 bitmap = BitmapFactory.decodeResource(resources, R.drawable.bulbonbody) } // 设置进度(外部调用) fun setProgress(progress: Float) { this.progress = progress.coerceIn(0f..1f) invalidate() } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) val bitmap = bitmap ?: return // 计算显示区域(从下往上) val showHeight = (bitmap.height * progress).toInt() val srcRect = Rect( 0, bitmap.height - showHeight, bitmap.width, bitmap.height ) // 绘制目标区域(适配 View 尺寸) val dstRect = Rect(0, 0, width, height) // 裁剪绘制 canvas.drawBitmap(bitmap, srcRect, dstRect, paint) } } 这部分代码只是在把图片拉长,并没有实现从下面开始使图片按比例可见
08-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值