Skip to content

Instantly share code, notes, and snippets.

@Coder-ACJHP
Created November 29, 2019 07:47
Show Gist options
  • Save Coder-ACJHP/8d3140d91e042f07661b01109acdee41 to your computer and use it in GitHub Desktop.
Save Coder-ACJHP/8d3140d91e042f07661b01109acdee41 to your computer and use it in GitHub Desktop.
Draw face rectangle on UIView by converting and transforming from UIGraphics coordinate to UIView coordinates with sample buffer in Swift 4.2
private func drawFaceRectangle(sampleBuffer: CMSampleBuffer, detectedFaceRect: CGRect) {
let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
let cameraImage = CIImage(cvPixelBuffer: pixelBuffer!)
// 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)
// Apply the transform to convert the coordinates
var faceViewBounds = detectedFaceRect.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
}
}
@fukemy
Copy link

fukemy commented Nov 27, 2021

Screen Shot 2021-11-27 at 18 28 53

@Coder-ACJHP
Copy link
Author

Screen Shot 2021-11-27 at 18 28 53

Hey @fukemy
This func copied from my project that’s why I forgot to edit missing components.
Simply you can define CAShapelayer to avoid these errors.
Happy Coding

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