generateBitmap 函数分析

本文探讨了generateBitmap函数的工作原理,该函数用于生成固定大小的Bitmap图像。通过对输入Bitmap进行裁切和居中处理,实现适应不同尺寸的需求。首先创建目标尺寸的空Bitmap,接着定义并偏移原始图像的裁切区域,最后在裁切区域内使用Canvas绘制源图像,实现在新的Bitmap中居中显示原始图像的目的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    static Bitmap generateBitmap(Bitmap bm, int width, int height) {
        if (bm == null) {
            return null;
        }

        bm.setDensity(DisplayMetrics.DENSITY_DEVICE);

        if (width <= 0 || height <= 0
                || (bm.getWidth() == width && bm.getHeight() == height)) {
            return bm;
        }

        // This is the final bitmap we want to return.
        try {
            Bitmap newbm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            newbm.setDensity(DisplayMetrics.DENSITY_DEVICE);

            Canvas c = new Canvas(newbm);
            Rect targetRect = new Rect();
            targetRect.right = bm.getWidth();
            targetRect.bottom = bm.getHeight();

            int deltaw = width - targetRect.right;
            int deltah = height - targetRect.bottom;

            if (deltaw > 0 || deltah > 0) {
                // We need to scale up so it covers the entire area.
                float scale;
                if (deltaw > deltah) {
                    scale = width / (float)targetRect.right;
                } else {
                    scale = height / (float)targetRect.bottom;
                }
                targetRect.right = (int)(targetRect.right*scale);
                targetRect.bottom = (int)(targetRect.bottom*scale);
                deltaw = width - targetRect.right;
                deltah = height - targetRect.bottom;
            }

            targetRect.offset(deltaw/2, deltah/2);

            Paint paint = new Paint();
            paint.setFilterBitmap(true);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
            c.drawBitmap(bm, null, targetRect, paint);

            bm.recycle();
            c.setBitmap(null);
            return newbm;
        } catch (OutOfMemoryError e) {
            Log.w(TAG, "Can't generate default bitmap", e);
            return bm;
        }
    }


该函数是生成一个固定大小 width * height 的 Bitmap 图像,源图像是由参数bm传递进来的 Bitmap 图像。

以系统自带壁纸为例,它们的分辨率都是1920*1280的,假如这里传入的参数width=800,,height=600,其实这里的width和height都是从文件/data/system/wallpaper_info.xml中读取到的,

/data/system # cat wallpaper_info.xml                             
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<wp width="800" height="600" name="res:com.android.launcher:drawable/wallpaper_chroma" />


我们先创建一个width*height大小的空图像,这也是最终要返回的,

Bitmap newbm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

接下来,进行的就是裁切工作,


根据代码流程,首先是定义了原始区域,即蓝色虚框

            targetRect.right = bm.getWidth();
            targetRect.bottom = bm.getHeight();

然后进行偏移,即红色虚框

   targetRect.offset(deltaw/2, deltah/2);

然后在可见的虚框区域,裁剪出指定的大小

   c.drawBitmap(bm, null, targetRect, paint);

这个时候的targetRect已经向左上方偏移了,可见区域变小,c是一个Canvas变量,类似定义了大小的一块画布,这块画布就是绿色区域标识的部分。

代码是按照上述方式实现的,但逻辑上,其实就是居中截取原始图像



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值