1

我很难在网上找到任何可以清楚地解释如何正确实现 Core Image 的 CIPerspectiveTransform 过滤器的文档。特别是,当为inputTopLeftinputTopRightinputBottomRight和设置 CIVector 值时,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 过滤器

4

2 回答 2

6

正如我对链接问题的评论,CIPerspectiveTransform在 iOS 5.1 的 Core Image 的 iOS 实现中不可用。这就是为什么您和其他提问者没有看到任何图像的原因,因为您的 CIFilter 很可能是 nil。

如果您只是想在图像上实现一种透视形式,那么在 iOS 上有两种不同的快速方法可以做到这一点,正如我在这个答案中所描述的那样。一种是在 UIImageView 的层上简单地使用正确类型的 CATransform3D,但这仅用于显示,不适用于图像调整。

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

于 2012-05-20T22:16:19.523 回答
0

Ooooold 帖子,但我敢打赌,仍然有人会寻找这种过滤器:

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

镜面效果示例

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

所以我在我的视图中添加了两个图像视图,如图所示。添加约束等

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

在此处输入图像描述

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 等

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

希望能帮助到你!

于 2018-12-14T17:40:09.607 回答