使用 CATransform3D 将矩形图像转换为四边形 [英] Transforming a rectangle image into a quadrilateral using a CATransform3D

查看:38
本文介绍了使用 CATransform3D 将矩形图像转换为四边形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个图像和一组四个点(描述一个四边形 Q).我想转换此图像,使其适合四边形 Q.Photoshop 将此转换称为扭曲".但根据这个四边形的来源(图像在空间中移动的视角),它实际上是一个尺度、一个旋转和一个透视矩阵的组合.

I have an image and a set of four points (describing a quadrilateral Q). I want to transform this image so that it is fits the quadrilateral Q. Photoshop calls this transformation "Distort." But according to the source of this quadrilateral (the perspective of the image moving in space), it is in fact the combination of a scale, a rotation and a perspective matrix.

我想知道使用 CATransform3D 4x4 矩阵是否可行.你有什么关于如何做到这一点的提示吗?我试图利用这四个点并建立 16 个方程(从 A' = A xu 中)但它不起作用:我不确定我应该使用什么作为 z、z'、w 和 w' 系数......

I am wondering if this is possible using a CATransform3D 4x4 matrix. Do you have any hints on how to do that? I've tried to take the four points and build 16 equations (out of A' = A x u) but it did not work: I'm not sure of what I should use as z, z', w and w' coefficients…

下图是我想要做的:

以下是一些要点示例:

276.523, 236.438,   517.656, 208.945,   275.984, 331.285,   502.23,  292.344
261.441, 235.059,   515.09,  211.5,     263.555, 327.066,   500.734, 295
229.031, 161.277,   427.125, 192.562,   229.16, 226,        416.48,  256

推荐答案

我已经创建了一个在 iOS 上执行此操作的工具包:https://github.com/hfossli/AGGeometryKit/

I've created a kit for doing this on iOS: https://github.com/hfossli/AGGeometryKit/

确保您的锚点在左上角 (CGPointZero).

Make sure your anchor point is top left (CGPointZero).

+ (CATransform3D)rectToQuad:(CGRect)rect
                     quadTL:(CGPoint)topLeft
                     quadTR:(CGPoint)topRight
                     quadBL:(CGPoint)bottomLeft
                     quadBR:(CGPoint)bottomRight
{
    return [self rectToQuad:rect quadTLX:topLeft.x quadTLY:topLeft.y quadTRX:topRight.x quadTRY:topRight.y quadBLX:bottomLeft.x quadBLY:bottomLeft.y quadBRX:bottomRight.x quadBRY:bottomRight.y];
}

+ (CATransform3D)rectToQuad:(CGRect)rect
                    quadTLX:(CGFloat)x1a
                    quadTLY:(CGFloat)y1a
                    quadTRX:(CGFloat)x2a
                    quadTRY:(CGFloat)y2a
                    quadBLX:(CGFloat)x3a
                    quadBLY:(CGFloat)y3a
                    quadBRX:(CGFloat)x4a
                    quadBRY:(CGFloat)y4a
{
    CGFloat X = rect.origin.x;
    CGFloat Y = rect.origin.y;
    CGFloat W = rect.size.width;
    CGFloat H = rect.size.height;

    CGFloat y21 = y2a - y1a;
    CGFloat y32 = y3a - y2a;
    CGFloat y43 = y4a - y3a;
    CGFloat y14 = y1a - y4a;
    CGFloat y31 = y3a - y1a;
    CGFloat y42 = y4a - y2a;

    CGFloat a = -H*(x2a*x3a*y14 + x2a*x4a*y31 - x1a*x4a*y32 + x1a*x3a*y42);
    CGFloat b = W*(x2a*x3a*y14 + x3a*x4a*y21 + x1a*x4a*y32 + x1a*x2a*y43);
    CGFloat c = H*X*(x2a*x3a*y14 + x2a*x4a*y31 - x1a*x4a*y32 + x1a*x3a*y42) - H*W*x1a*(x4a*y32 - x3a*y42 + x2a*y43) - W*Y*(x2a*x3a*y14 + x3a*x4a*y21 + x1a*x4a*y32 + x1a*x2a*y43);

    CGFloat d = H*(-x4a*y21*y3a + x2a*y1a*y43 - x1a*y2a*y43 - x3a*y1a*y4a + x3a*y2a*y4a);
    CGFloat e = W*(x4a*y2a*y31 - x3a*y1a*y42 - x2a*y31*y4a + x1a*y3a*y42);
    CGFloat f = -(W*(x4a*(Y*y2a*y31 + H*y1a*y32) - x3a*(H + Y)*y1a*y42 + H*x2a*y1a*y43 + x2a*Y*(y1a - y3a)*y4a + x1a*Y*y3a*(-y2a + y4a)) - H*X*(x4a*y21*y3a - x2a*y1a*y43 + x3a*(y1a - y2a)*y4a + x1a*y2a*(-y3a + y4a)));

    CGFloat g = H*(x3a*y21 - x4a*y21 + (-x1a + x2a)*y43);
    CGFloat h = W*(-x2a*y31 + x4a*y31 + (x1a - x3a)*y42);
    CGFloat i = W*Y*(x2a*y31 - x4a*y31 - x1a*y42 + x3a*y42) + H*(X*(-(x3a*y21) + x4a*y21 + x1a*y43 - x2a*y43) + W*(-(x3a*y2a) + x4a*y2a + x2a*y3a - x4a*y3a - x2a*y4a + x3a*y4a));

    const double kEpsilon = 0.0001;

    if(fabs(i) < kEpsilon)
    {
        i = kEpsilon* (i > 0 ? 1.0 : -1.0);
    }

    CATransform3D transform = {a/i, d/i, 0, g/i, b/i, e/i, 0, h/i, 0, 0, 1, 0, c/i, f/i, 0, 1.0};

    return transform;
}

我不相信这段代码.我所做的只是在互联网上搜索并整理各种不完整的答案.

I take no credit for this code. All I did was scouring the internet and put together various incomplete answers.

这篇关于使用 CATransform3D 将矩形图像转换为四边形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆