Skip to content

Instantly share code, notes, and snippets.

@Coder-ACJHP
Last active March 14, 2022 12:17
Show Gist options
  • Save Coder-ACJHP/571eac3da8b3d3437116e1353602d5fa to your computer and use it in GitHub Desktop.
Save Coder-ACJHP/571eac3da8b3d3437116e1353602d5fa to your computer and use it in GitHub Desktop.
SplitMirror filter with UIGraphics applied on UIImage
//
// 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
}
@Coder-ACJHP
Copy link
Author

Coder-ACJHP commented Mar 1, 2022

The filter tested with single image and it works well without memory issue but I think it needs to optimization for using in real time camera feed.
If some body would like to help and create Core Image version it will be appreciated.

Filter result looks like this
splitMirrored

@Coder-ACJHP
Copy link
Author

Coder-ACJHP commented Mar 14, 2022

Now I'll create this filter via using Core Image to reduce memory usage and improve performance

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)
   }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment