Android自定义控件之可平移、缩放、旋转图片控件

Android自定义控件之可平移、缩放、旋转图片控件,第1张

先上效果图

源码

单点拖动对进行平移 *** 作。双手缩放大小和旋转到一定的角度。缩放的时候 不能大于最大的缩放因子和小于最小的缩放因子。大于最大缩放因子或者小于最小缩放因子需要对图像进行回d。旋转的角度只能为90度的倍数,不满足90度要进行回d。回d要一个渐变的效果。

大体思路: 首先,Android中提供了Matrix类可以对图像进行处理。其次,要显示一张最容易想到的就是ImageView。回d要求渐变的过程,可以通过属性动画进行设置。所以大体的思路是:继承ImageView,重写onTouchEvent()方法,判断事件类型,在对应的事件使用Matrix对图像进行变换。

Matrix是一个已经封装好的矩阵,最重要的作用就是对坐标点进行变换。

举个栗子:

1某个点(x0,y0,1)通过单位矩阵E映射得到的点还是(x0,y0,1)。

3点(x0,y0,1)通过矩阵T映射得到的点就会做如下的变换

可以看到点(x0,y0,1)经过T矩阵在x轴方向上平移了dx,在y轴方向上平移了dy。

通过以上的变换可以得到具体的思路: 我们维护一个图像对应的矩阵mCurrentMatrix,该矩阵主要是对ImageView中的图像的各个点进行映射。ImageView在容器位置摆放完成之后,置mCurrentMatrix矩阵为单位矩阵。当onTouchEvent()方法中触发单点触控并且手指进行平移的时候,调用矩阵mCurrentMatrix的postTranslate(dx,dy),对mCurrentMatrix进行变换。当手指抬起,利用变换结束后的矩阵对图像的各个点进行映射,从而得到平移变换后的图像。同理可得,在两只手指进行缩放旋转的时候,我们对矩阵mCurrentMatrix进行各种变换,当缩放旋转的事件结束再利用变换完的矩阵去映射图像的各个点,从而得到缩放、旋转后的图像。

安卓自定义View进阶 - Matrix原理

安卓自定义View进阶 - Matrix详解

首先理清事件的逻辑:

初始化图像大小和位置

缩放图像大小和控件大小自适应,平移图像中心和控件中心重合

onTouchEvent()函数

平移 *** 作

将图像对应的矩阵进行变换。

缩放 *** 作

mBoundRectF为记录图像边界的矩形。缩放的时候选取图像的中心进行缩放。

旋转 *** 作

旋转的时候旋转的旋转中心也是图像的中心

图像中各个点的映射

调用ImageView的setImageMatrix(Matrix matrix)会让ImageView根据设置的matrix去重新绘制图像。

更新图像的矩形边界

获得图像的矩形,并根据矩阵映射矩形各个点的坐标

缩放回d

旋转回d

一些计算方法

要求图像的变换是一个渐变的过程,很容易想到的就是属性动画。因为属性动画本身就是对值进行不断set的过程。而我们维护的矩阵也是一个值,所以很自然可以想到,如果得到回d之前的矩阵的值以及回d之后矩阵的值,就可以根据动画监听器中动画当前的系数值去改变矩阵的值。

对animator对象设置完监听器之后,就可以在手指抬起的时候调用属性动画的start()方法开启动画。

自定义可平移、缩放、旋转的控件主要点有两个方面:一是onTouchEvent()中判断平移、旋转、缩放的触发条件,平移位移量、缩放比例因子、旋转角度的计算。二是Matrix矩阵的应用。

3d变换我们首先要弄清楚坐标轴的方向, 3D变形的坐标轴则是X,Y,Z三条轴组成的立体空间,X轴正方向是朝右,Y周正方向是朝下,Z轴正方向是朝屏幕外

假定都是在三维空间中,平面坐标应该更加简单,刻画一个点的向量应该: [x, y, z]

所谓变换矩阵就是指,该矩阵 X 坐标向量 可以得到变换后的新坐标,满足如下性质

< "平移"后 的坐标> = < 平行移动变换矩阵> X <原始坐标>

< "缩放"后 的坐标> = < 缩放移动变换矩阵> X <原始坐标>

< "旋转"后 的坐标> = < 旋转移动变换矩阵> X <原始坐标>

< "斜切"后 的坐标> = < 斜切移动变换矩阵> X <原始坐标>

初始化的变换矩阵

初始化的变换乘法后的结果

所以matrix3d的默认值

观察者站轴的正方向看向负方向,旋转物体,逆时针为负,顺时针为正。

其中有

可以得到旋转矩阵

移动的变换矩阵

dx: x轴移动的距离

dy: y轴移动的距离

dz: z轴移动的距离

缩放的变换矩阵

斜切是最不好理解的,符合右手定则,如果y轴斜切角度,是指垂直Y轴逆时针旋转一定的角度后的坐标

在前端开发中,我们采用的动画方案有主帧动画 、 补间动画、骨骼动画 等等

借助css3的transform,我们可以实现很流畅的补间动画

如果物体发生了上面的几种变换,可以把上面所有矩阵依次序相乘,然后就得到了最终的变换矩阵

由此我们可以看出来 一个css变换举证 M 总可以写成一个

M = SRT

其中 S 是缩放举证 R 是旋转矩阵 T是缩放举证

变换过程中,我们可以对S R T 分别实现补间动画,来进行变换动画

从“相对移动”的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。在OpenGL中,实现这两种功能甚至使用的是同样的函数。

由于模型和视图的变换都通过矩阵运算来实现,在进行变换前,应先设置当前 *** 作的矩阵为“模型视图矩阵”。设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数,像这样:

glMatrixMode(GL_MODELVIEW);

通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。这也只需要一行代码:

glLoadIdentity();

然后,就可以进行模型变换和视图变换了。进行模型和视图变换,主要涉及到三个函数:

glTranslate,把当前矩阵和一个表示移动物体的矩阵相乘。三个参数分别表示了在三个坐标上的位移值。

glRotate,把当前矩阵和一个表示旋转物体的矩阵相乘。物体将绕着(0,0,0)到(x,y,z)的直线以逆时针旋转,参数angle表示旋转的角度。

glScale,把当前矩阵和一个表示缩放物体的矩阵相乘。x,y,z分别表示在该方向上的缩放比例。

注意我都是说“与XX相乘”,而不是直接说“这个函数就是旋转”或者“这个函数就是移动”,这是有原因的,马上就会讲到。

假设当前矩阵为单位矩阵,然后先乘以一个表示旋转的矩阵R,再乘以一个表示移动的矩阵T,最后得到的矩阵再乘上每一个顶点的坐标矩阵v。所以,经过变换得到的顶点坐标就是((RT)v)。由于矩阵乘法的结合率,((RT)v) = (R(Tv)),换句话说,实际上是先进行移动,然后进行旋转。即:实际变换的顺序与代码中写的顺序是相反的。由于“先移动后旋转”和“先旋转后移动”得到的结果很可能不同,初学的时候需要特别注意这一点。

OpenGL之所以这样设计,是为了得到更高的效率。但在绘制复杂的三维图形时,如果每次都去考虑如何把变换倒过来,也是很痛苦的事情。这里介绍另一种思路,可以让代码看起来更自然(写出的代码其实完全一样,只是考虑问题时用的方法不同了)。

让我们想象,坐标并不是固定不变的。旋转的时候,坐标系统随着物体旋转。移动的时候,坐标系统随着物体移动。如此一来,就不需要考虑代码的顺序反转的问题了。

以上都是针对改变物体的位置和方向来介绍的。如果要改变观察点的位置,除了配合使用glRotate和glTranslate函数以外,还可以使用这个函数:gluLookAt。它的参数比较多,前三个参数表示了观察点的位置,中间三个参数表示了观察目标的位置,最后三个参数代表从(0,0,0)到 (x,y,z)的直线,它表示了观察者认为的“上”方向。

以上就是关于Android自定义控件之可平移、缩放、旋转图片控件全部的内容,包括:Android自定义控件之可平移、缩放、旋转图片控件、CSS3 matrix3d矩阵变换和动画变换、opengl如何获取到变换的最终矩阵等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9541801.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-29
下一篇2023-04-29

发表评论

登录后才能评论

评论列表(0条)

    保存