I wanna control crop area in ImagePicker - swift

After selecting the image from the gallery, I can crop it as a still frame to crop it. I don't want this. I want to be able to change the crop size. I want to be able to change the crop area like in the second gif. How can I do this without resorting to a 3rd party library ?
Image Picker Manager:
class ImagePickerManager: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var picker = UIImagePickerController();
var alert = UIAlertController(title: "Fotoğraf Seç", message: nil, preferredStyle: .actionSheet)
var viewController: UIViewController?
var pickImageCallback : ((UIImage) -> ())?;
override init(){
super.init()
let cameraAction = UIAlertAction(title: "Kamerayı Aç", style: .default){
UIAlertAction in
self.openCamera()
}
let galleryAction = UIAlertAction(title: "Galeriden Seç", style: .default){
UIAlertAction in
self.openGallery()
}
let cancelAction = UIAlertAction(title: "İptal", style: .cancel){
UIAlertAction in
}
// Add the actions
picker.allowsEditing = true
picker.delegate = self
alert.addAction(cameraAction)
alert.addAction(galleryAction)
alert.addAction(cancelAction)
}
func pickImage(_ viewController: UIViewController, _ callback: #escaping ((UIImage) -> ())) {
pickImageCallback = callback;
self.viewController = viewController;
alert.popoverPresentationController?.sourceView = self.viewController!.view
viewController.present(alert, animated: true, completion: nil)
}
func openCamera(){
alert.dismiss(animated: true, completion: nil)
if(UIImagePickerController .isSourceTypeAvailable(.camera)){
picker.sourceType = .camera
self.viewController!.present(picker, animated: true, completion: nil)
} else {
let alertController: UIAlertController = {
let controller = UIAlertController(title: "Warning", message: "You don't have camera", preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default)
controller.addAction(action)
return controller
}()
viewController?.present(alertController, animated: true)
}
}
func openGallery(){
alert.dismiss(animated: true, completion: nil)
picker.sourceType = .photoLibrary
self.viewController!.present(picker, animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[.editedImage] as? UIImage {
pickImageCallback?(image)
} else if let image = info[.originalImage] as? UIImage {
pickImageCallback?(image)
}
picker.dismiss(animated: true, completion: nil)
}
#objc func imagePickerController(_ picker: UIImagePickerController, pickedImage: UIImage?) {
}
}
My code result:
I want do this:

Related

UIImage Text Overlay - CGPoint Incorrect; Wrong Image Size?

I'm trying to overlay text on the bottom-left corner of a UIImage. I get the image from the device's camera roll, perform the overlay, then assign it to a UIImageView on a ViewController. The vertical CGPoint is never correct, however, as the height of the image seems to be different than what I'm getting from view.bounds.height. The following is what I've been working with; what change should I make to be able to get the correct CGPoint to assign the overlay label to? Thanks!
Result (should be bottom-left):
class PhotosVC: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
#IBOutlet weak var photoView: UIImageView!
func presentPicker() {
let picker = UIImagePickerController()
picker.delegate = self
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: {
action in
picker.sourceType = .camera
self.present(picker, animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "Photo Library", style: .default, handler: {
action in
picker.sourceType = .photoLibrary
self.present(picker, animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
presentPicker()
}
override func viewDidLoad() {
super.viewDidLoad()
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true, completion: nil)
guard let image = info[.originalImage] as? UIImage else {
print("Issue getting photo from imagePickerController")
return }
let CGPointBottomLeft = photoView.bounds.height
print(photoView.bounds.height) // Is 336
let imageWithText = textToImage(drawText: "Overlayed text", inImage: image, atPoint: CGPoint(x: 0, y: CGPointBottomLeft))
self.photoView.image = imageWithText
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
func textToImage(drawText text: String, inImage image: UIImage, atPoint point: CGPoint) -> UIImage {
let textColor = UIColor.white
let textFont = UIFont(name: "Helvetica Bold", size: 212)! // Only visible if huge
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(image.size, false, scale)
let textFontAttributes = [
NSAttributedString.Key.font: textFont,
NSAttributedString.Key.foregroundColor: textColor,
] as [NSAttributedString.Key : Any]
image.draw(in: CGRect(origin: CGPoint.zero, size: image.size))
let rect = CGRect(origin: point, size: image.size)
text.draw(in: rect, withAttributes: textFontAttributes)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}

Unable to form a Circular Image in Swift

I have used the following code in my view controller to display the image either from a camera or from the photo library in the circular form. But, I am not getting the desired result as there image is not filling up the entire circle. I have showed my code and the screenshot of the resulting image below. Appreciate your help! Thanks!
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var image1: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
image1.makeRounded()
}
}
//MARK:- Image Picker
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
//This is the tap gesture added on my UIImageView.
#IBAction func didTapOnImageView(sender: UITapGestureRecognizer) {
//call Alert function
showAlert()
}
//Show alert to selected the media source type.
private func showAlert() {
let alert = UIAlertController(title: "Image Selection", message: "From where you want to pick this image?", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: {(action: UIAlertAction) in
self.getImage(fromSourceType: .camera)
}))
alert.addAction(UIAlertAction(title: "Photo Album", style: .default, handler: {(action: UIAlertAction) in
self.getImage(fromSourceType: .photoLibrary)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .destructive, handler: nil))
present(alert, animated: true, completion: nil)
}
//get image from source type
private func getImage(fromSourceType sourceType: UIImagePickerController.SourceType) {
//Check is source type available
if UIImagePickerController.isSourceTypeAvailable(sourceType) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.sourceType = sourceType
present(imagePickerController, animated: true, completion: nil)
}
}
//MARK:- UIImagePickerViewDelegate.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
dismiss(animated: true) { [weak self] in
guard let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else { return }
//Setting image to your image view
self?.image1.image = image
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true)
}
}
extension UIImageView {
func makeRounded() {
layer.borderWidth = 1
layer.masksToBounds = false
layer.borderColor = UIColor.black.cgColor
layer.cornerRadius = frame.height / 2
clipsToBounds = true
}
}
It because your image is not square
You need to change your imageView content mode to aspect fill in the xib or storyboard
or you can do it by code too
imageView.contentMode = .scaleAspectFill
extension UIImageView {
func makeRounded() {
self.layer.borderWidth = 1
self.layer.masksToBounds = false
self.layer.borderColor = UIColor.black.cgColor
self.layer.cornerRadius = self.frame.height / 2
self.clipsToBounds = true
self.contentMode = .scaleAspectFill
}
}

Selected image won't change previously displayed image

I've got a simple set up to select an image from either camera or photo library. When I select a new photo, it doesn't change from the original photo that the app loads with.
I'm thinking it has something to do with the hierarchy (not sure if I'm using that in correct terms) of the code. I read my code as the image I select, I then set the variable "originalImage" to the selected image. So that should display right? Well, spoiler, I'm wrong.
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var originalImage = UIImage(named: "crossSection2.jpg")!
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = originalImage
}
#IBAction func onCameraClicked(_ sender: Any) {
let ac = UIAlertController(title: "Choose Image", message: nil, preferredStyle: .actionSheet)
ac.addAction(UIAlertAction(title: "Camera", style: .default, handler: { (action) in
self.showPicker(sourceType: .camera)
}))
ac.addAction(UIAlertAction(title: "Library", style: .default, handler: { (action) in
self.showPicker(sourceType: .photoLibrary)
}))
ac.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
self.present(ac, animated: true, completion: nil)
}
func showPicker(sourceType: UIImagePickerController.SourceType) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = sourceType
self.present(picker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingImage newImage : UIImage, editingInfo: [String : AnyObject]?) {
dismiss(animated: true, completion: nil)
self.originalImage = newImage
self.imageView.image = newImage
}
}
From https://developer.apple.com/documentation/uikit/uiimagepickercontrollerdelegate/1619152-imagepickercontroller
Deprecated Use imagePickerController:didFinishPickingMediaWithInfo:
instead.
so, try changing your code to:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
dismiss(animated: true, completion: nil)
self.originalImage = info[.originalImage] as! UIImage
self.imageView.image = (info[.originalImage] as! UIImage)
}
You need to update your UIImageView, not only "originalImage". Try:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingImage newImage : UIImage, editingInfo: [String : AnyObject]?) {
dismiss(animated: true, completion: nil)
self.originalImage = newImage
self.imageView.image = newImage
}

How do I add an image taken by camera or galery to a button?

I'm using an UIImagePickerController to choose a source to take a picture from. This picture should be set to an UIButton.
I know you can add an UIImage to an UIButton by string, like
someButton.setImage(UIImage(named:...)), but I need to set it by a variable which I create with taking the picture.
#IBOutlet weak var addPictureOutlet: UIButton!
func chooseSource() {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
let kameraAction = UIAlertAction(title: "Kamera",
style: .default) { (action) in
imagePickerController.sourceType = .camera
self.present(imagePickerController, animated: true, completion: nil)
}
let libraryAction = UIAlertAction(title: "Galerie",
style: .default) { (action) in
imagePickerController.sourceType = .photoLibrary
self.present(imagePickerController, animated: true, completion: nil)
}
let cancelAction = UIAlertAction(title: "Cancel",
style: .cancel)
let alert = UIAlertController(title: "Quelle",
message: "Wählen sie eine Quelle für die Klausur.",
preferredStyle: .actionSheet)
alert.addAction(kameraAction)
alert.addAction(libraryAction)
alert.addAction(cancelAction)
self.present(alert, animated: true) {
}
}
#IBAction func addPicture(_ sender: UIButton) {
chooseSource()
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image1 = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
addPictureOutlet.setImage(image1, for: .normal)
}
}
I've tried this, but I can't really figure out why it doesn't work, there is no error while compiling or running and the UIImage of the UIButton does not change.
You should use like that. You cannot use a func in an action.
#IBOutlet weak var addPictureOutlet: UIButton!
func chooseSource() {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
let kameraAction = UIAlertAction(title: "Kamera",
style: .default) { (action) in
imagePickerController.sourceType = .camera
self.present(imagePickerController, animated: true, completion: nil)
}
let libraryAction = UIAlertAction(title: "Galerie",
style: .default) { (action) in
imagePickerController.sourceType = .photoLibrary
self.present(imagePickerController, animated: true, completion: nil)
}
let cancelAction = UIAlertAction(title: "Cancel",
style: .cancel)
let alert = UIAlertController(title: "Quelle",
message: "Wählen sie eine Quelle für die Klausur.",
preferredStyle: .actionSheet)
alert.addAction(kameraAction)
alert.addAction(libraryAction)
alert.addAction(cancelAction)
self.present(alert, animated: true) {
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image1 = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
addPictureOutlet.setImage(image1, for: .normal)
}
#IBAction func addPicture(_ sender: UIButton) {
chooseSource()
}
As you said it is not going into imagePicker method, it seems you have missed delegate to work imagePicker method properly
Add UIImagePickerControllerDelegate and create a variable to assign UIImagePickerController var imagePicker = UIImagePickerController()
and set imagePicker.delegate = self

image not show in uiimageview

i want to get image from library but, image not show until I choose from library
this is my code
#IBAction func btnProfile(_ sender: UIButton) {
let alert = UIAlertController(title: "Change Profil Image", message: "Pilih Foto", preferredStyle: UIAlertControllerStyle.actionSheet)
alert.addAction(UIAlertAction(title: "Gunakan Kamera", style: .default, handler: { (action: UIAlertAction!) in
print("Gunakan Kamera")
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera){
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.camera;
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
}
}))
alert.addAction(UIAlertAction(title: "Ambil Foto dari Galery", style: .default, handler: { (action: UIAlertAction!) in
print("Ambil Foto dari Galery")
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary){
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary;
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action: UIAlertAction!) in
print("Cancel")
}))
present(alert, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let image = info[.originalImage] as? UIImage else { return } // error in here >> 'UIImage?' is not convertible to 'UIImage' >> and warning yellow >> Cast from 'Slice<Dictionary<UIImagePickerController.InfoKey, Any>>' (aka 'Slice<Dictionary<NSString, Any>>') to unrelated type 'UIImage' always fails
picker.dismiss(animated: true, completion: nil)
imgProf.image = image
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
I want to display the image on UIimageview, but after I retrieve it from the library it doesn't always appear,
error in guard let image, and warning yellow in there
i use swift 3
this is UIImagePickerControllerDelegate
public protocol UIImagePickerControllerDelegate : NSObjectProtocol {
#available(iOS 2.0, *)
optional public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
#available(iOS 2.0, *)
optional public func imagePickerControllerDidCancel(_ picker: UIImagePickerController)
}
I tried this code and it worked
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var selectedImageFromPicker: UIImage?
if let editedImage = info[UIImagePickerControllerEditedImage] as? UIImage {
selectedImageFromPicker = editedImage
} else if let originalImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
selectedImageFromPicker = originalImage
}
if let selectedImage = selectedImageFromPicker {
imgProf.image = selectedImage
}
dismiss(animated: true, completion: nil)
}
and thanks for #Kamran, your answer for change the position is true
self.present(imagePicker, animated: true, completion: {
imagePicker.delegate = self
})
Set picker delegate in completion.