Last active
March 14, 2022 12:17
-
-
Save Coder-ACJHP/571eac3da8b3d3437116e1353602d5fa to your computer and use it in GitHub Desktop.
SplitMirror filter with UIGraphics applied on UIImage
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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 | |
} |
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
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