原文 了解Android Matrix转换

很多年前,在学校我学习了矩阵。 我记不太清楚了,但我记得的是在想,“但是......你对这些知识做了什么呢?”

快进几年,我开始作为Android开发人员工作,不得不使用ImageViewscaleType - 如果你看过所有可能的类型,你已经注意到其中一个是matrix 。 多年来,我一直避开它,使用其他规模类型或解决问题。 然而几周前我正在开发一种设计,其中组件的背景图像应该与视图的左上角对齐,而不执行任何缩放,如下所示:

所以我继续添加了一个ImageView并再次浏览了所有scaleType - 希望有一个我错过的类型,但是在我尝试使用scaleType="matrix"它们都没有完全正确,它完全符合我的要求。 但为什么这有效呢? 它实际上做了什么?

所以我看了一下Matrix文档:

Matrix类包含一个3x3矩阵,用于转换坐标

嗯......不是很有帮助。 幸运的是,我并不是唯一一个不懂的人, Arnaud Bos写了一篇很棒的文章 ,详细解释了背后的数学(警告:如果你打算阅读它 - 可能需要一杯咖啡(或者两杯)的时间)。 如果你在那篇文章的中途迷路了,我不能责怪你 - 这很复杂,但好消息是你不必理解数学就能用matrix(虽然它很有帮助。

我们怎样才能使用Matrix

正如我之前提到的,我们必须在ImageView上设置scaleType="matrix" 。 但要真正能够使用它,我们必须在代码中设置imageMatrix

imageView.imageMatrix = Matrix().apply {// perform transformations
}
复制代码

现在我们有了这个 - 我们可以用它做什么? 矩阵支持一系列不同的变换,如translatescalerotateskew 。 如果这些听起来很熟悉,因为它们(大多数)与View,动画或画布上的相同。

您会发现,对于每个操作,都有一setpre版本。 稍后我会谈到这一点,但是现在我们只使用set版本。

所以,我们能做些什么?

Translating (移动)

设置translation意味着将图像移动到其他位置。 您所要做的就是使用Matrix上所需的xy坐标调用setTranslate

val dWidth = imageView.drawable.intrinsicWidth
val dHeight = imageView.drawable.intrinsicHeightval vWidth = imageView.measuredWidth
val vHeight = imageView.measuredHeight
setTranslate(round((vWidth - dWidth) * 0.5f),round((vHeight - dHeight) * 0.5f)
)
复制代码

在这个例子中,我们只是将drawable置于View中心,这导致与在ImageView上设置scaleType="center"相同的行为。 那么让我们来看看ImageView如何做到这一点:

mDrawMatrix.setTranslate(Math.round((vwidth - dwidth) * 0.5f),Math.round((vheight - dheight) * 0.5f));
复制代码

它完全一样! 所以我们不知道它已经使用了矩阵变换。

Scaling (缩放)

Scaling(正如您可能已经猜到的那样)定义了图像的大小。 您可以定义两个值 - 一个用于x轴,另一个用于y轴。 但是,通过缩放,您还可以设置轴心点。

枢轴点定义转换将保持不变的点。 默认情况下它是0, 0 - 左上角 - 意味着图像将向右和向下延伸,左上角保持不变 - 就像左边的上面的gif一样。

如果要从中心缩放图像(如右侧的gif),可以将轴设置为图像的中心,如下所示:

setScale(0.5f, 0.5f, dWidth / 2f, dHeight / 2f)复制代码

这将使图像缩放到其大小的一半,其中心的枢轴点。 如果你只想从左上角缩放它,你可以省略最后两个参数,如下所示:

setScale(0.5f, 0.5f)
复制代码

但是你可以用缩放做更多的事情。 如果提供负比例值,则基本上可以围绕轴(或两个)镜像图像。 相当漂亮!

Rotation (旋转)

你猜对了! 通过旋转,您可以旋转图像。 在这里,我们提供了我们想要旋转的角度,以及一个类似于比例的可选枢轴点。

  setRotate(45f,dWidth / 2f,dHeight / 2f) 复制代码

将图像围绕图像中心旋转45度。 如果将它旋转-45度,它将向左旋转。

Skewing (倾斜)

倾斜可能是你以前没有听说过的转变。 倾斜将沿轴(或两个)拉伸您的图像,就像上面的GIF一样。 我们来看一个例子:

  setSkew(1f,0f,dWidth / 2f,dHeight / 2f) 复制代码

这会使图像在x轴(以及中心点周围)偏斜1,这是图像的宽度,导致图像倾斜45度,就像上面的gif一样。

应用多个转换

我们现在可以translatescalerotateskew图像,但是如果我们想要将它们组合起来呢? 显而易见的事情可能是连续调用多个set方法。 但是,这只会应用最后一次转换 - 所有以前的转换都将被覆盖。 这是因为set方法基本上重置了Matrix

但正如我之前提到的,还有每个转换的post版本。 通过使用这些,我们可以应用多个变换,并真正利用matrix的魔力。

但是pre的区别是什么? 对于第一次转换,使用三种版本中的哪一种没有区别,但对于任何未来的转换,它可以产生很大的不同。

假设我们想要将图像转换为视图的中心并将其缩放到一半大小。 这两个版本将产生预期的效果:

val drawableLeft = round((vWidth - dWidth) * 0.5f)
val drawableTop = round((vHeight - dHeight) * 0.5f)
// Version 1
setTranslate(drawableLeft, drawableTop)
val (viewCenterX, viewCenterY) = vWidth / 2f to vHeight / 2f
postScale(0.5f, 0.5f, viewCenterX, viewCenterY)
// Version 2
setTranslate(drawableLeft, drawableTop)
val (drawableCenterX, drawableCenterY) = dWidth / 2f to dHeight / 2f
preScale(0.5f, 0.5f, drawableCenterX, drawableCenterY)
复制代码

请注意,在第一个版本中,我们使用postScale和视图的中心,而在第二个版本中,我们使用preScaledrawable的中心。

使用postScale ,将在translate后应用比例转换。 由于图像已经在视图中居中,我们必须使用视图的中心点作为枢轴。

val (viewCenterX, viewCenterY) = vWidth / 2f to vHeight / 2f
postScale(0.5f, 0.5f, viewCenterX, viewCenterY)
复制代码

所以从头开始回顾这个例子 - 为什么应用scaleType="matrix"只是起作用? 使用默认martix,比例将为1,平移,旋转和倾斜将为0,因此图像将在左上角绘制。 所以它完全符合我的需要!

下次您必须以默认scaleType不起作用的方式布局图像时 - 尝试使用Matrix

了解Android Matrix转换相关推荐

  1. Android Matrix的代码验证和应用

    Matrix介绍 : Android Matrix的用法总结(链接:ttp://blog.csdn.net/jdsjlzx/article/details/52741445) 代码验证 前面讲到的各种 ...

  2. Android Bitmap转换WebP图片导致损坏的分析及解决方案

    Android Bitmap转换WebP图片导致损坏的分析及解决方案 参考文章: (1)Android Bitmap转换WebP图片导致损坏的分析及解决方案 (2)https://www.cnblog ...

  3. android Matrix图片变换处理

    今天,讲讲android  Matrix图片变换处理的内容. Matrix 对于一个图片变换的处理,需要Matrix类的支持,它位于"android.graphics.Matrix&qu ...

  4. android中调用fft函数,J使用PCM数据在Android中转换FFT(JTransforms FFT in Android from PCM data)...

    J使用PCM数据在Android中转换FFT(JTransforms FFT in Android from PCM data) 我一直在玩这个游戏已经有一段时间了,我无法弄清楚我在这里要做的事情. ...

  5. Android pdf转换bitmap保存到本地

    Android pdf转换bitmap保存到本地 PDF转换成图片保存到本地 Android有自带的API提供 首先要把PDF文件下载到本地,下载成功使用 下载就最简单的IO下载都行 例如: try ...

  6. android 单位转换工具,Android单位转换工具类

    Android单位转换工具类 Android单位转换工具类主要由以下4部分构成 1.这个类不能被初始化 2.dip转px接口 3.sp转px接口 4.px转dip接口 代码如下: import and ...

  7. 一、Android Matrix 矩阵

    一.Android矩阵 大学学的线性代数和矩阵基本忘记的差不多了,理解起矩阵Matrix着实有点费劲,记了一次笔记还把左乘右乘记错了. 1.1 使用场景 项目中会使用到矩阵的场景: 背景图片,指定位置 ...

  8. 仿抖音短视频系统源码,android 时间戳转换

    仿抖音短视频系统源码,android 时间戳转换相关的代码 package util;import java.text.SimpleDateFormat; import java.util.Calen ...

  9. 视频格式转换器android,佳佳Android视频格式转换器(Android视频转换软件)V12.0.1.0 免费版...

    佳佳Android视频格式转换器(Android视频转换软件)是一款功能强大的Android安卓手机视频格式转换工具.佳佳Android视频格式转换器(Android视频转换软件)可以轻松快捷的将原本 ...

最新文章

  1. PKUWC2020游记与题面整理
  2. Django模板语法
  3. stylus之插值(Interpolation)
  4. word2vec相似度计算_干货|文本相似度计算
  5. Qt窗口操作函数(最大化,全屏,隐藏最大化,最小化)
  6. SQL语句中AND OR运算符优先级
  7. 【BZOJ5251】【九省联考2018】—劈配(网络流)
  8. Python入门——爬取pubmed文献做分析
  9. 开关电源和LDO的区别
  10. 贪婪模式与正则匹配过程
  11. chip在计算机英语什么意思,chip是什么意思中文翻译
  12. 西安电子科技大学经济与管理学院861上岸学姐考研经验分享
  13. IOS版aplayer使用教程_享声数播APP使用指南【ios版】
  14. LeetCode 21. 合并两个有序链表(链表)
  15. 智慧旅游景区Web3D可视化GIS综合运营平台
  16. Java实现台阶问题
  17. mysql组复制搭建
  18. 基于stm32单片机电子秤设计
  19. 面试常问MySQL性能优化问题
  20. Outlook Express邮件客户端的自动化配置

热门文章

  1. 一个把ListString转化为以,隔开的字符串的方法
  2. 构建布局良好的windows程序
  3. KITTI IMU 原始100Hz数据 (里面数据有重复)
  4. 《淘宝网开店 拍摄 修图 设计 装修 实战150招》一一1.17 如何选择合适的拍摄地点...
  5. 关于Android这个名字。。。
  6. 交叉表的简单实现2:使用前端程序实现
  7. 自定义弹出框控件制作及示例
  8. 树莓派Raspberry Pi 16G SD卡刷系统时默认空间扩容
  9. ADO.NET 快速入门(四):从数据库填充 DataSet
  10. udp_socket聊天器demo