Warhol is a lightweight Swift wrapper around Apple's Vision framework for face detection on iOS. It detects face features from camera or image input, converts those positions into your coordinate space, and lets you draw or place images directly on top.
- Face detection from camera input
- Face detection from
UIImageView - Face feature conversion into view coordinates
- Overlay drawing and image placement on top of landmarks
- iOS 12.0+
- Swift 5.9+
.package(url: "https://github.com/toupper/Warhol.git", from: "0.2.1")platform :ios, '12.0'
use_frameworks!
target 'MyApp' do
pod 'Warhol', '~> 0.2'
endgithub "toupper/Warhol" ~> 0.2
import Warhol
let cameraViewController = CameraFaceDetectionViewController()
let faceView = FaceView()
faceView.backgroundColor = .clear
cameraViewController.cameraFrontView = faceView
present(cameraViewController, animated: true)Create a custom view conforming to CameraFrontView and draw using the incoming FaceViewModel:
import Warhol
final class FaceView: UIView, CameraFrontView {
var viewModel: FaceViewModel?
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext(),
let viewModel else {
return
}
context.saveGState()
defer { context.restoreGState() }
context.addRect(viewModel.boundingBox)
}
}let cameraViewController = CameraFaceDetectionViewController()
let leftEye = ImageLayout(image: UIImage(named: "leftEye")!, sizeRatio: SizeRatio(width: 1, height: 4))
let rightEye = ImageLayout(image: UIImage(named: "rightEye")!, sizeRatio: SizeRatio(width: 1, height: 4))
let nose = ImageLayout(image: UIImage(named: "nose")!)
let faceLayout = FaceLayout(
landmarkLayouts: [
.leftEye: leftEye,
.rightEye: rightEye,
.nose: nose,
]
)
cameraViewController.faceLayout = faceLayout
present(cameraViewController, animated: true)You can also implement CameraFaceDetectionDelegate if you want landmark updates without drawing.
Draw directly into the existing image view:
import Warhol
imageView.image = UIImage(named: "Face")
drawLandmarks(in: imageView, draw: { viewModel, context in
// draw with CGContext
}, error: { error in
print(error)
})Generate a new image instead of mutating the existing one:
imageView.image = UIImage(named: "Face")
drawLandmarksInNewImage(from: imageView, draw: { viewModel, context in
// draw with CGContext
}, completion: { newImage in
self.newImageView.image = newImage
}, error: { error in
print(error)
})Warhol is released under the MIT license. See LICENSE for details.

