简体   繁体   English

如何将这个UIGraphics图像操作转换为Core Image?

[英]How to convert this UIGraphics image operation to Core Image?

I write SplitMirror filter like in Apple Motion app or Snapchat lenses by using UIGraphics to use it with real time camera feed or video processing, with single image request it works well like in attached image in the question but for multiple filtering request not.我像在 Apple Motion 应用程序或 Snapchat 镜头中一样编写SplitMirror过滤器,通过使用UIGraphics将其与实时相机馈送或视频处理一起使用,对于单个图像请求,它像问题中的附加图像一样工作良好,但对于多个过滤请求则不然。 I think it's code must be changed from UIGraphics to Core Image & CIContext for better performance and less memory usage like CIFilters and actually I don't know how to do it.我认为它的代码必须从UIGraphics更改为Core Image & CIContext以获得更好的性能并减少 memory 像CIFilters这样的使用,实际上我不知道该怎么做。 I tried several ways to convert it but I stuck on merging left and right, this can be done with `CICategoryCompositeOperations filters but which one is fit this case I o have idea, so need some help with this issue.我尝试了几种方法来转换它,但我坚持左右合并,这可以通过 `CICategoryCompositeOperations 过滤器来完成,但我知道哪种适合这种情况,所以需要一些帮助来解决这个问题。

Filter code using UIGraphics :使用UIGraphics过滤代码:

//
//  SplitMirror filter.swift
//  Image Editor
// 
//  Created by Coder ACJHP on 25.02.2022.
// 
// SnapChat & Tiktok & Motion App like image filter
// Inspired from 'https://support.apple.com/tr-tr/guide/motion/motn169f94ea/mac'
// Splits an image in half vertically and reverses the left remaining half to create a reflection.

final func splitMirrorFilter(processingImage image: UIImage) -> UIImage {
    // Image size
    let imageSize = image.size

    // Left half
    let leftHalfRect = CGRect(
        origin: .zero,
        size: CGSize(
                width: imageSize.width/2,
                height: imageSize.height
                )
    )
    
    // Right half
    let rightHalfRect = CGRect(
        origin: CGPoint(
            x: imageSize.width - (imageSize.width/2).rounded(),
            y: 0
        ),
        size: CGSize(
            width: imageSize.width - (imageSize.width/2).rounded(),
            height: imageSize.height
        )
    )
    // Split image into two parts
    guard let cgRightHalf = image.cgImage?.cropping(to: rightHalfRect) else { return image }
    // Flip right side to be used as left side
    let flippedLeft = UIImage(cgImage: cgRightHalf, scale: image.scale, orientation: .upMirrored)
    let unFlippedRight = UIImage(cgImage: cgRightHalf, scale: image.scale, orientation: image.imageOrientation)
    
    UIGraphicsBeginImageContextWithOptions(imageSize, false, image.scale)
    
    flippedLeft.draw(at: leftHalfRect.origin)
    unFlippedRight.draw(at: rightHalfRect.origin)
    
    guard let splitMirroredImage = UIGraphicsGetImageFromCurrentImageContext() else { return image }
    UIGraphicsEndImageContext()
    return splitMirroredImage
}

结果看起来像

Here is what it tried with Core Image这是它对Core Image的尝试

    // Splits an image in half vertically and reverses the left remaining half to create a reflection.
final func splitMirrorFilterCIImageVersion(processingImage image: UIImage) -> CIImage? {

    
    guard let ciImageCopy = CIImage(image: image) else { return image.ciImage }
    
    // Image size
    let imageSize = ciImageCopy.extent.size
    let imageRect = CGRect(origin: .zero, size: imageSize)

    // Left half
    let leftHalfRect = CGRect(
        origin: .zero,
        size: CGSize(
                width: imageSize.width/2,
                height: imageSize.height
                )
    )
    
    // Right half
    let rightHalfRect = CGRect(
        origin: CGPoint(
            x: imageSize.width - (imageSize.width/2).rounded(),
            y: 0
        ),
        size: CGSize(
            width: imageSize.width - (imageSize.width/2).rounded(),
            height: imageSize.height
        )
    )
    
    
    
    // Split image into two parts
    let cgRightHalf = ciImageCopy.cropped(to: rightHalfRect)
    context.draw(cgRightHalf.oriented(.upMirrored), in: leftHalfRect, from: imageRect)
    context.draw(cgRightHalf, in: rightHalfRect, from: imageRect)
    
    // I'm stuck here
    
    // Merge two images into one 
    // Here I don't know which filter can be used to merge op
    // CICategoryCompositeOperation filters may fits
}

I think you are on the right track.我认为你在正确的轨道上。

You can create the left half from the right half by applying transformations to it using let leftHalf = rightHalf.transformed(by: transformation) .您可以通过使用let leftHalf = rightHalf.transformed(by: transformation)对其应用转换来从右半部分创建左半部分。 The transformation should mirror it and translate it to the correct position, ie, next to the right half.转换应该对其进行镜像并将其转换为正确的 position,即紧邻右半部分。

You can them combine the two into one image using let result = leftHalf.composited(over: rightHalf) and render that result using a CIContext .您可以使用let result = leftHalf.composited(over: rightHalf)将两者组合成一个图像,并使用CIContext渲染该结果。

After getting the correct idea from Frank Schlegel 's answer I rewrote filter code and now works well.Frank Schlegel的回答中得到正确的想法后,我重写了过滤器代码,现在运行良好。

 // Splits an image in half vertically and reverses the left remaining half to create a reflection.
final func splitMirrorFilterCIImageVersion(processingImage image: UIImage) -> CIImage? {
    
    guard let ciImageCopy = CIImage(image: image) else { return image.ciImage }
    
    // Image size
    let imageSize = ciImageCopy.extent.size
    
    // Right half
    let rightHalfRect = CGRect(
        origin: CGPoint(
            x: imageSize.width - (imageSize.width/2).rounded(),
            y: 0
        ),
        size: CGSize(
            width: imageSize.width - (imageSize.width/2).rounded(),
            height: imageSize.height
        )
    )
            
    // Split image into two parts
    let ciRightHalf = ciImageCopy.cropped(to: rightHalfRect)
    // Make transform to move right part to left
    let transform = CGAffineTransform(translationX: -rightHalfRect.size.width, y: -rightHalfRect.origin.y)
    // Create left part and apply transform then flip it
    let ciLeftHalf = ciRightHalf.transformed(by: transform).oriented(.upMirrored)
            
    // Merge two images into one
    return ciLeftHalf.composited(over: ciRightHalf)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM