一个简单的例子,说明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还有很多使用强大的接口,感兴趣的同学可以系统深入探索下。尤其是工作学习当中涉及到图片缩放、裁剪、旋转、平移等操作的同学,更应该学习下。

相关推荐
小满zs4 分钟前
React第十二章(useSyncExternalStore)
前端·javascript·react.js
Mrs_Lupin7 分钟前
React核心思维模型(一)
前端·react.js·前端框架
你不讲 wood19 分钟前
预览 PDF 文档
开发语言·前端·javascript·pdf·html·node·文件预览
我就说好玩39 分钟前
基于echarts、php、Mysql开发的数据可视化大屏
前端·后端·信息可视化·echarts
2301_7891695440 分钟前
ai说ajax
前端·javascript·ajax
小白讲前端1 小时前
炫酷的登录框!(附源码)
前端·javascript·css·html
二川bro1 小时前
CSS兼容处理
前端·css
XiaoYu20021 小时前
31.JS高级-包管理工具详解
前端·javascript·程序员
终将超越过去2 小时前
Element Plus在Vue3的安装
前端·javascript·vue.js
xu_duo_i2 小时前
Vxe UI 表格行编辑(默认不显示编辑框,点击后可编辑)
前端·vue.js·ui·vxe