我很难在网上找到任何文档来清楚地解释如何正确实现 Core Image 的 CIPerspectiveTransform 过滤器。特别是,当设置 CIVector 值时 inputTopLeft, inputTopRight, inputBottomRight, , 和 inputBottomLeft, ,这些向量对图像做了什么?(即,这些向量如何扭曲我的图像背后的数学原理是什么?)

目前这是我正在使用的代码。它不会崩溃,但不显示图像:

CIImage *myCIImage = [[CIImage alloc] initWithImage:self.image];
CIContext *context = [CIContext contextWithOptions:nil];
CIFilter *filter = [CIFilter filterWithName:@"CIPerspectiveTransform" keysAndValues:@"inputImage", myCIImage, @"inputTopLeft", [CIVector vectorWithX:118 Y:484], @"inputTopRight", [CIVector vectorWithX:646 Y:507], @"inputBottomRight", [CIVector vectorWithX:548 Y:140], @"inputBottomLeft", [CIVector vectorWithX:155 Y:153], nil];
CIImage *outputImage = [filter outputImage];
CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *transformedImage = [UIImage imageWithCGImage:cgimg];
[self setImage:transformedImage];
CGImageRelease(cgimg);

其他可能很重要的注意事项:

  • 我的 UIImageView (75pts x 115 pts) 已经通过 awakeFromNib 初始化,并且已经有一个与其关联的图像 (151px x 235px)。

  • 上面的代码是在UIImageView中实现的 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 功能。我希望能够根据屏幕坐标调整图像的视角,使图像看起来像是在 3D 空间中移动。

  • 此代码适用于 iPhone 应用程序。

同样,我认为我要问的问题是各种参数向量的作用,但我可能问错了问题。

下面的帖子非常相似,但询问的是为什么他的图像消失了,而不是如何使用 CIVectors 进行 CIPerspectiveTransform。它也没有受到多少关注,也许是因为它太笼统了:如何使用 CIPerspectiveTransform 过滤器

有帮助吗?

解决方案

正如我对链接问题的评论,CIPerspectiveTransform 是 自 iOS 5.1 起,在 Core Image 的 iOS 实现中不可用. 。这就是为什么你和另一个提问者没有看到任何图像的原因,因为很可能你的 CIFilter 为零。

如果您只想在图像上实现某种形式的透视,在 iOS 上有两种不同的快速方法可以实现此目的,正如我在 这个答案. 。一种是简单地使用 正确的 CATransform3D 类型 在 UIImageView 的图层上,但这仅对显示有用,对图像调整不起作用。

第二种方法是在 OpenGL ES 中使用适当的 3-D 变换矩阵来操作图像。正如我在上面链接的答案中指出的,我有 一个开源框架 包含了所有这些,其中的 FilterShowcase 示例有一个将透视应用于传入视频的示例。您可以轻松地将视频输入替换为图像,并在应用透视效果后从中抓取图像。

其他提示

太老了,但我敢打赌有人仍然会寻找这种过滤器:

以下函数将滤镜应用于图像并返回具有透视效果的相同图像,尝试创建具有透视效果的反射效果。(下图仅为示例,并非真实测试结果)

Example of mirror effect

这是一个示例,因此您需要进行一些调整。目的是创建一个似乎反映“主要”图像的图像。

因此,我在视图中添加了两个图像视图,如图所示。增加了约束条件等。

然后在 func 中,您将看到坐标是硬编码的,因此返回的图像将完美匹配其容器(底部 UIImageView)。

enter image description here

func applyperspectiveTransform(imagen: UIImage) -> UIImage
{

      var context = CIContext()
    var outputImage = CIImage()
    var newUIImage = UIImage()

    let leftTop     = CGPoint(x: self.ImgView.frame.origin.x, y: self.ImgReflection.frame.origin.y + self.ImgReflection.frame.size.height)
    let leftBottom  = CGPoint(x: self.ImgReflection.frame.origin.x, y: self.ImgView.frame.origin.y + self.ImgView.frame.size.height)
    let rightTop    = CGPoint(x: self.ImgView.frame.origin.x + self.ImgView.frame.size.width, y: self.ImgReflection.frame.origin.y + self.ImgReflection.frame.size.height)
    let rightBottom = CGPoint(x: self.ImgReflection.frame.origin.x + self.ImgReflection.frame.size.width, y: self.ImgView.frame.origin.y + self.ImgView.frame.size.height)

    let lT = CIVector(x: leftTop.x, y: leftTop.y)
    let lB = CIVector(x: leftBottom.x, y: leftBottom.y)
    let rT = CIVector(x: rightTop.x, y: rightTop.y)
    let rB = CIVector(x: rightBottom.x, y: rightBottom.y)

    let aCIImage = CIImage(image: imagen)
    context = CIContext(options: nil);

    let perspectiveTransform = CIFilter(name: "CIPerspectiveTransform")!

    perspectiveTransform.setValue(lB,forKey: "inputTopLeft")
    perspectiveTransform.setValue(rB,forKey: "inputTopRight")
    perspectiveTransform.setValue(rT,forKey: "inputBottomRight")
    perspectiveTransform.setValue(lT,forKey: "inputBottomLeft")
    perspectiveTransform.setValue(aCIImage,forKey: kCIInputImageKey)

    outputImage = perspectiveTransform.outputImage!
    let cgimg = context.createCGImage(outputImage, from: outputImage.extent)
    newUIImage = UIImage(cgImage: cgimg!)

    return newUIImage
}

对于这个特定的效果(镜像),您可能需要添加更多效果,例如渐变、更改 alpha 等

快乐编码!希望能帮助到你

希望能帮助到你!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top