一个简单的例子,说明Matrix类的妙用

在Android、前端或者别的平台的软件开发中,有时会遇到类似如下需求:

  1. 将某个图片显示到指定的区域;
  2. 要求不改变图片本身的宽高比,进行缩放;
  3. 要求最大限度的居中填充到显示区域。

以下示意图可以简单描绘该需求

以Android平台为例,如果我们的目标显示对象为Imageview,那么很简单,只要如下设置即可

xml 复制代码
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:scaleType="fitCenter"
    android:src="@drawable/image" />

其中实现以上需求最关键的代码为 android:scaleType="fitCenter"。感兴趣的同学可以去查看源码,探究scaleType属性设置为fitCenter之后底层代码是如何实现的。

但是,如果我们的显示区域只是一个自定义view中特定坐标的区域,如(x1, y1, x2, y2)的矩形区域。不了解Matrix的同学,可能第一反应就是根据图片本身的宽高以及目标显示区域的宽高,去计算一个缩放比,如下代码:

java 复制代码
public void drawBitmapFillRegion(Canvas canvas, Bitmap bitmap, Rect targetRect) {
    // 目标区域的宽高
    int targetWidth = targetRect.width();
    int targetHeight = targetRect.height();

    // Bitmap 的宽高
    int bitmapWidth = bitmap.getWidth();
    int bitmapHeight = bitmap.getHeight();

    // 计算宽高比
    float scale = Math.max((float) targetWidth / bitmapWidth, (float) targetHeight / bitmapHeight);

    // 计算缩放后的宽高
    float scaledWidth = scale * bitmapWidth;
    float scaledHeight = scale * bitmapHeight;

    // 计算偏移
    float offsetX = targetRect.left + (targetWidth - scaledWidth) / 2;
    float offsetY = targetRect.top + (targetHeight - scaledHeight) / 2;

    // 设置 Matrix 进行缩放和平移
    Matrix matrix = new Matrix();
    matrix.setScale(scale, scale);
    matrix.postTranslate(offsetX, offsetY);

    // 绘制 Bitmap
    canvas.drawBitmap(bitmap, matrix, null);
}

但是,当你深入研究Matrix中的方法,你就会发现,根本不需要这么麻烦,以下几句即可简单完美实现

java 复制代码
public void drawBitmapFillRegion(Canvas canvas, Bitmap bitmap) {
    // 定义源矩形,即 Bitmap 的边界
    RectF srcRect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
    RectF srcRect = new RectF(x1, y1, x2, y2);

    // 设置 Matrix 进行缩放和平移
    Matrix matrix = new Matrix();
    matrix.setRectToRect(srcRect, targetRect, Matrix.ScaleToFit.CENTER);

    // 绘制 Bitmap
    canvas.drawBitmap(bitmap, matrix, null);
}

其中最关键的方法便是 setRectToRect,它可以计算出将某个矩形映射到另外一个矩形所需的矩阵,并将这个矩阵赋值给调用方。其实,Matrix还有很多使用强大的接口,感兴趣的同学可以系统深入探索下。尤其是工作学习当中涉及到图片缩放、裁剪、旋转、平移等操作的同学,更应该学习下。

相关推荐
weixin_403810132 小时前
AI智能体写安卓自动化脚本教程:Cursor/Trae+CLI 实战,自然语言生成代码
android·人工智能·自动化·跨境电商·安卓自动化脚本·多账户运营
ly76892 小时前
HTML5 从入门到工程实践:语义化、表单、多媒体、性能与项目规范详解
前端·html·html5
呆呆小孩3 小时前
零基础学 MySQL(上):从建库建表到增删改查,一篇搭好 SQL 基础
android·sql·mysql
catchadmin4 小时前
NativePHP v4 让 Blade 构建原生 iOS 与 Android 界面
android·ios·ai·php
FfHUCisI5 小时前
Golang 数据库连接池深度调优
android·数据库·golang
人民广场吃泡面6 小时前
前端该重视的编程思想
前端
冬夜戏雪6 小时前
agent的trace 和eval
开发语言·前端·javascript
IT_陈寒6 小时前
Redis的DEL命令居然没删干净数据?这个坑我爬了半天
前端·人工智能·后端