我已经在Android上开发了一个应用程序,你可以在屏幕上添加图片,然后在周围移动/旋转/缩放它们。从技术上讲,我有一个固定的方面父布局,其中包含这些图像(图像视图)。它们设置了宽度和高度以匹配父级。然后,我可以将他们的位置保存在服务器上,稍后我可以将其加载到相同或其他设备上。基本上,我只保存矩阵值。但是,平移X/Y有绝对值(以像素为单位),但屏幕大小不同,因此我将其设置为百分比值(因此平移X除以父级宽度,平移Y除以父级高度)。加载图像时,我只需将转换x/y乘以父布局的宽度/高度,即使在不同的设备上,所有内容看起来都一样。
我是这样做的:
float[] values = new float[9];
parentLayout.matrix.getValues(values);
values[Matrix.MTRANS_X] /= parentLayout.getWidth();
values[Matrix.MTRANS_Y] /= parentLayout.getHeight();
然后在加载函数中,我简单地将这些值相乘。
图像操作是通过使用后平移/后缩放/后旋转和定位点(对于2指手势,它是这些手指之间的中点)来完成的。
现在,我想将这个应用程序移植到iOS,并使用类似的技术在iOS设备上实现正确的图像位置。CGaffinetTransform与矩阵类非常相似。字段的顺序不同,但它们的工作方式似乎相同。
假设这个数组是来自Android应用程序的示例值数组:
let a: [CGFloat] = [0.35355338, -0.35355338, 0.44107446, 0.35355338, 0.35355338, 0.058058262]
我不保存最后3个字段,因为它们总是0、0和1,而在iOS上,它们甚至无法设置(文档还说明它是[0、0、1])。这就是“转换”的样子:
let tx = a[2] * width //multiply percentage translation x with parent width
let ty = a[5] * height //multiply percentage translation y with parent height
let transform = CGAffineTransform(a: a[0], b: a[3], c: a[1], d: a[4], tx: tx, ty: ty)
然而,这只适用于非常简单的情况。对于其他的图像通常是错位的,甚至是完全混乱。
我注意到,默认情况下,在Android上,我在[0,0]中有定位点,但在iOS上,它是图像的中心。
例如:
float midX = parentLayout.getWidth() / 2.0f;
float midY = parentLayout.getHeight() / 2.0f;
parentLayout.matrix.postScale(0.5f, 0.5f, midX, midY);
给出以下矩阵:
0.5, 0.0, 360.0,
0.0, 0.5, 240.0,
0.0, 0.0, 1.0
[360.0,240.0]只是来自左上角的向量。
但是,在iOS上,我不需要提供中间点,因为它已经围绕中心进行了转换:
let transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
它给了我:
CGAffineTransform(a: 0.5, b: 0.0, c: 0.0, d: 0.5, tx: 0.0, ty: 0.0)
我尝试在iOS上设置不同的锚定点:
parentView.layer.anchorPoint = CGPoint(x: 0, y: 0)
但是,我不能得到正确的结果。我试过用-width*0.5、-height*0.5、scale和translate-back进行翻译,但结果和Android不一样。
简而言之:我如何将矩阵从Android修改为cgaffinettransform从iOS来实现相同的外观?
我还附上尽可能简单的演示项目。目标是在iOS项目中将输出数组从android复制到“a”数组中,并修改cgaffinettransform计算(和/或parentview设置),使图像在两个平台上看起来都一样,无论android的日志输出是什么。
安卓:
https://github.com/piotrros/MatrixAndroid
网间网操作系统:
https://github.com/piotrros/MatrixIOS
编辑:
@Sulthan解决方案非常有效!尽管如此,我还是提出了一个关于逆转过程的子问题,这也是我需要的。在他的回答中,我尝试将其融入到我的应用程序中:
let savedTransform = CGAffineTransform.identity
.concatenating(CGAffineTransform(translationX: -width / 2, y: -height / 2))
.concatenating(
self.transform
)
.concatenating(CGAffineTransform(translationX: width / 2, y: height / 2))
let tx = savedTransform.tx
let ty = savedTransform.ty
let t = CGAffineTransform(a: savedTransform.a, b: savedTransform.b, c: savedTransform.c, d: savedTransform.d, tx: tx / cWidth, ty: ty / cHeight)
placement.transform = [Float(t.a), Float(t.c), Float(t.tx), Float(t.b), Float(t.d), Float(t.ty), 0, 0, 1]
Placement只是一个用来存放矩阵“android”版本的类。cwidth/cheight是父级的宽度/高度。我将tx/ty除以它们得到宽度/高度的百分比,就像我在Android上做的那样。
但是,它不起作用。Tx/Ty错误。
输入:
[0.2743883,-0.16761175,0.43753636,0.16761175,0.2743883,
0.40431038,0.0,0.0,1.0]
它还给我们:
[0.2743883,-0.16761175,0.18834576,0.16761175,0.2743883,0.2182884,
0、0、1
所以除了Tx/Ty以外的一切都很好。错误在哪里?