Skip to content

Instantly share code, notes, and snippets.

@Coder-ACJHP
Created November 20, 2019 07:34
Show Gist options
  • Save Coder-ACJHP/aabb43711543309d0891ff002046a705 to your computer and use it in GitHub Desktop.
Save Coder-ACJHP/aabb43711543309d0891ff002046a705 to your computer and use it in GitHub Desktop.
This method gets sample buffer and converts it to image than draws face rect on shape layer on UIKit
fileprivate func drawFaceFrame(sampleBuffer: CMSampleBuffer) {
let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
let cameraImage = CIImage(cvPixelBuffer: pixelBuffer!)
let faces = faceDetector?.features(in: cameraImage)
// For converting the Core Image Coordinates to UIView Coordinates
let ciImageSize = cameraImage.extent.size
var transform = CGAffineTransform(scaleX: 1, y: -1)
transform = transform.translatedBy(x: 0, y: -ciImageSize.height)
for face in faces as! [CIFaceFeature] {
// Apply the transform to convert the coordinates
var faceViewBounds = face.bounds.applying(transform)
// Calculate the actual position and size of the rectangle in the image view
let viewSize = self.layer.bounds.size
let scale = min(viewSize.width / ciImageSize.width,
viewSize.height / ciImageSize.height)
let offsetX = (viewSize.width - ciImageSize.width * scale) / 2
let offsetY = (viewSize.height - ciImageSize.height * scale) / 2
faceViewBounds = faceViewBounds.applying(CGAffineTransform(scaleX: scale, y: scale))
faceViewBounds.origin.x += offsetX
faceViewBounds.origin.y += offsetY
let faceRect = faceViewBounds.insetBy(dx: -40, dy: -40)
DispatchQueue.main.async {
if self.shapeLayer == nil {
self.shapeLayer = CAShapeLayer()
self.shapeLayer.name = "CornersLayer"
self.shapeLayer.strokeColor = UIColor.white.cgColor
self.shapeLayer.fillColor = UIColor.clear.cgColor
self.shapeLayer.lineWidth = 7.0
self.shapeLayer.lineCap = .round
self.shapeLayer.lineJoin = .round
self.shapeLayer.frame = self.layer.bounds
self.layer.addSublayer(self.shapeLayer)
}
let cornerLengthToShow = self.layer.bounds.size.height * 0.04
// Create Paths Using BeizerPath for all four corners
let topLeftCorner = UIBezierPath()
topLeftCorner.move(to: CGPoint(x: faceRect.minX, y: faceRect.minY + cornerLengthToShow))
topLeftCorner.addLine(to: CGPoint(x: faceRect.minX, y: faceRect.minY))
topLeftCorner.addLine(to: CGPoint(x: faceRect.minX + cornerLengthToShow, y: faceRect.minY))
let topRightCorner = UIBezierPath()
topRightCorner.move(to: CGPoint(x: faceRect.maxX - cornerLengthToShow, y: faceRect.minY))
topRightCorner.addLine(to: CGPoint(x: faceRect.maxX, y: faceRect.minY))
topRightCorner.addLine(to: CGPoint(x: faceRect.maxX, y: faceRect.minY + cornerLengthToShow))
let bottomRightCorner = UIBezierPath()
bottomRightCorner.move(to: CGPoint(x: faceRect.maxX, y: faceRect.maxY - cornerLengthToShow))
bottomRightCorner.addLine(to: CGPoint(x: faceRect.maxX, y: faceRect.maxY))
bottomRightCorner.addLine(to: CGPoint(x: faceRect.maxX - cornerLengthToShow, y: faceRect.maxY ))
let bottomLeftCorner = UIBezierPath()
bottomLeftCorner.move(to: CGPoint(x: faceRect.minX, y: faceRect.maxY - cornerLengthToShow))
bottomLeftCorner.addLine(to: CGPoint(x: faceRect.minX, y: faceRect.maxY))
bottomLeftCorner.addLine(to: CGPoint(x: faceRect.minX + cornerLengthToShow, y: faceRect.maxY))
let combinedPath = CGMutablePath()
combinedPath.addPath(topLeftCorner.cgPath)
combinedPath.addPath(topRightCorner.cgPath)
combinedPath.addPath(bottomRightCorner.cgPath)
combinedPath.addPath(bottomLeftCorner.cgPath)
self.shapeLayer.path = combinedPath
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment