Reputation: 895
Here's my problem. I'm using UIImagePickerController to take a picture from the camera. After it's been taken (and because I set allowsEditing to TRUE), the preview image shows a white rectangle delimiting the default cropping area (which doesn't appear to be in the center of the picture).
What I want is to set a custom Camera Overlay that matches exactly that cropping area so that the user knows exactly that the picture he took will be the resulting image after cropping.
See picture below, basically I want the Camera Overlay to only display the red rectangle that represents the cropping rectangle in the preview.
Any idea on how to implement this so it will work on all type of Iphone device (iphone 4, 5, 6, 6 plus) and Portrait/Landscape mode ?
Thanks for your help.
Upvotes: 6
Views: 4479
Reputation: 8279
To place a square in the center of your screen to give the user a 'guide' as to where they should be focusing the camera, do the following:
1) Add an extension to UIScreen
and get an exact square based on either the height or width of screen (depending on if in landscape or not):
extension UIScreen {
func fullScreenSquare() -> CGRect {
var hw:CGFloat = 0
var isLandscape = false
if UIScreen.main.bounds.size.width < UIScreen.main.bounds.size.height {
hw = UIScreen.main.bounds.size.width
}
else {
isLandscape = true
hw = UIScreen.main.bounds.size.height
}
var x:CGFloat = 0
var y:CGFloat = 0
if isLandscape {
x = (UIScreen.main.bounds.size.width / 2) - (hw / 2)
}
else {
y = (UIScreen.main.bounds.size.height / 2) - (hw / 2)
}
return CGRect(x: x, y: y, width: hw, height: hw)
}
func isLandscape() -> Bool {
return UIScreen.main.bounds.size.width > UISc reen.main.bounds.size.height
}
}
2) Then write a method that you will utilize this to create a guide for the camera overlay:
func guideForCameraOverlay() -> UIView {
let guide = UIView(frame: UIScreen.main.fullScreenSquare())
guide.backgroundColor = UIColor.clear
guide.layer.borderWidth = 4
guide.layer.borderColor = UIColor.red.cgColor
guide.isUserInteractionEnabled = false
return guide
}
3) Add the guide to your overlay:
picker.cameraOverlayView = guideForCameraOverlay()
BONUS Handle Orientation Change
In the class that you create your UIImagePickerController
:
// Add this line where you instantiate your image picker
self.imagePicker.view.layer.addObserver(self, forKeyPath: "bounds", options: .new, context: nil)
And listen to the bounds change on the camera to reset the guide in the center of the screen:
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "bounds" {
if let picker = mediaPicker, picker.cameraCaptureMode == .photo {
picker.cameraOverlayView = nil
picker.cameraOverlayView = guideForCameraOverlay()
}
}
}
And don't forget to remove the observer when you are finished:
self.imagePicker.view.layer.removeObserver(self, forKeyPath: "bounds")
Upvotes: 2
Reputation: 944
You can use the following 3rd party library https://github.com/gekitz/GKImagePicker
self.myPicker = [[GKImagePicker alloc] init];
self.myPicker.delegate = self;
self.myPicker.cropSize = CGSizeMake([FunctionUtils getViewWidth], [FunctionUtils getViewWidth]/ratio);
and set appropriate crop size for the same.
Upvotes: 1