Swift images get stretched - swift

So I am totally new to programming and swift, this is my second week of trying to code. A lot of fun but a lot of errors as well. So I want to make an app where the user can choose a photo from their gallery or make a photo using there camera, and after a press of a button, this image will get pixalised(using the Core Image function).
The problem is whenever I press the button, the image seems to get stretched, and I can't figure out why. After browsing a picture:
After pressing the button:
Thanks for any answers!
My code is as follows:
import UIKit
class ViewController: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
#IBOutlet weak var myImageView: UIImageView!
let picker = UIImagePickerController()
func noCamera(){
let alertVC = UIAlertController(title: "No Camera", message: "Don't try it on a computer Dumbass!", preferredStyle: .Alert)
let okAction = UIAlertAction(title: "Sorry about that :(", style:.Default, handler: nil)
alertVC.addAction(okAction)
presentViewController(alertVC, animated: true, completion: nil)
}
#IBAction func photofromLibrary(sender: UIBarButtonItem) {
picker.allowsEditing = false //2
picker.sourceType = .PhotoLibrary //3
picker.modalPresentationStyle = .Popover
presentViewController(picker, animated: true, completion: nil)//4
picker.popoverPresentationController?.barButtonItem = sender
}
#IBAction func shootPhoto(sender: UIButton) {
if UIImagePickerController.availableCaptureModesForCameraDevice(.Rear) != nil {
picker.allowsEditing = false
picker.sourceType = UIImagePickerControllerSourceType.Camera
picker.cameraCaptureMode = .Photo
presentViewController(picker, animated: true, completion: nil)
} else {
noCamera()
}
}
#IBAction func pixelise(sender: UIButton) {
// 1
let ciImage = CIImage(image: myImageView.image)
// 2
var filter = CIFilter(name: "CIPixellate")
filter.setDefaults()
filter.setValue(ciImage, forKey: kCIInputImageKey)
myImageView.contentMode = .ScaleAspectFit
// 3
var outputImage = filter.outputImage
var newImage = UIImage(CIImage: outputImage)
myImageView.image = newImage
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
picker.delegate = self
}
//MARK: Delegates
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
var chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage //2
myImageView.contentMode = .ScaleAspectFit //3
myImageView.image = chosenImage //4
dismissViewControllerAnimated(true, completion: nil) //5
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

The process of converting CIImage to UIImage consists of creating a CIContext, then creating a CGImage using that context, and then creating a UIImage from that:
// 1
let ciImage = CIImage(image: image)
// 2
let filter = CIFilter(name: "CIPixellate")
filter.setDefaults()
filter.setValue(ciImage, forKey: kCIInputImageKey)
// 3
let context = CIContext(options: nil)
let cgImage = context.createCGImage(filter.outputImage, fromRect: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
let outputImage = UIImage(CGImage: cgImage)
That yields:

Related

How to share generated UIImage with siwft 4

Hi I use this function to create an UIImage of QRCode
func generateQRCode(string: String){
let data = string.data(using: String.Encoding.ascii)
if let filter = CIFilter(name: "CIQRCodeGenerator") {
filter.setValue(data, forKey: "inputMessage")
let transform = CGAffineTransform(scaleX: 3, y: 3)
if let output = filter.outputImage?.transformed(by: transform) {
imageQRCode.image = UIImage(ciImage: output)
qrImage = UIImage(ciImage: output)
self.tableView.reloadData()
}
}
}
After I have generated the image I want to save or print it.
I used this function
let shareText = NSLocalizedString("SHARE_QR_TITLE", comment: "")
if let image = qrImage {
let vc = UIActivityViewController(activityItems: [shareText, image], applicationActivities: [])
present(vc, animated: true)
}
but I can't share it. I received this error: "[ShareSheet] connection invalidate"
Try this it's work for me but not showing qrcode by sharing in whatsApp. Working fine with messages, mail, telegram..
import UIKit
class QRCodeGeneratorViewController: UIViewController {
#IBOutlet var qrImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func generateQRCode(from string: String) -> UIImage? {
let data = string.data(using: String.Encoding.ascii)
if let filter = CIFilter(name: "CIQRCodeGenerator") {
filter.setValue(data, forKey: "inputMessage")
let transform = CGAffineTransform(scaleX: 3, y: 3)
if let output = filter.outputImage?.transformed(by: transform) {
return UIImage(ciImage: output)
}
}
return nil
}
#IBAction func generateQRAction(_ sender: Any) {
let image = generateQRCode(from: "iOS Developer")
qrImageView.image = image
}
#IBAction func btnShareClk(_ sender: Any) {
let shareText = "Hello, world!"
if let image = qrImageView.image {
let vc = UIActivityViewController(activityItems: [shareText, image], applicationActivities: [])
present(vc, animated: true)
vc.popoverPresentationController?.sourceView = self.qrImageView
}
}

Image Classifer does not show results in Classification Label in Xcode

I tried to make an image classification app. For some reason, the classification label doesn't show any results. Below is my code, would appreciate all your helps.enter image description here
===
import UIKit
import CoreML
import Vision
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var myImageView: UIImageView!
let picker = UIImagePickerController()
#IBAction func cameraButton(_ sender: UIBarButtonItem) {
let vc = UIImagePickerController()
vc.sourceType = .camera
vc.allowsEditing = false
vc.delegate = self
present(vc, animated: true)
}
#IBAction func photoButton(_ sender: UIBarButtonItem) {
picker.allowsEditing = false
picker.sourceType = .photoLibrary
picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
present(picker, animated: true, completion: nil)
}
#IBOutlet weak var classificationLabel: UILabel!
/// Image classification
lazy var classificationRequest: VNCoreMLRequest = {
do {
let model = try VNCoreMLModel(for: AnimalClassifier().model)
let request = VNCoreMLRequest(model: model, completionHandler: { [weak self] request, error in
self?.processClassifications(for: request, error: error)
})
request.imageCropAndScaleOption = .centerCrop
return request
} catch {
fatalError("Failed to load Vision ML model: \(error)")
}
}()
func updateClassifications(for Image: UIImage) {
classificationLabel.text = "Classifying..."
let orientation = CGImagePropertyOrientation(Image.imageOrientation)
guard let ciImage = CIImage(image: Image) else { fatalError("Unable to create \(CIImage.self) from \(Image).") }
DispatchQueue.global(qos: .userInitiated).async {
let handler = VNImageRequestHandler(ciImage: ciImage, orientation: orientation)
do {
try handler.perform([self.classificationRequest])
} catch {
print("Failed to perform classification.\n\(error.localizedDescription)")
}
}
}
func processClassifications(for request: VNRequest, error: Error?) {
DispatchQueue.main.async {
guard let results = request.results else {
self.classificationLabel.text = "Unable to classify image.\n\(error!.localizedDescription)"
return
}
let classifications = results as! [VNClassificationObservation]
if classifications.isEmpty {
self.classificationLabel.text = "Nothing recognized."
} else {
// Display top classifications ranked by confidence in the UI.
let topClassifications = classifications.prefix(2)
let descriptions = topClassifications.map { classification in
// Formats the classification for display; e.g. "(0.37) cliff, drop, drop-off".
return String(format: " (%.2f) %#", classification.confidence, classification.identifier)
}
self.classificationLabel.text = "Classification:\n" + descriptions.joined(separator: "\n")
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
picker.delegate = self
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
var Image: UIImage
if let possibleImage = info[.editedImage] as? UIImage {
Image = possibleImage
} else if let possibleImage = info[.originalImage] as? UIImage {
Image = possibleImage
} else {
return
}
myImageView.image = Image
dismiss(animated: true)
updateClassifications(for: Image)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
}
To make your label support multiple lines you need to set the property numberOfLines to 0. So in viewDidLoad for instance do
classificationLabel.numberOfLines = 0

video imagePickerController cancel not working

I am using custom CropViewController open source imagePicker for photos, and for video I'm trying to use default imagePicker provided by Swift itself since CropViewController doesn't have video option.
After I pick a video from photo library, three buttons shown at the bottom (cancel, play, select). Play button and select button works perfectly but cancel won't work.
Here is my code to trigger imagePickerController for both photo and video.
#objc func videoPresentPicker() {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .photoLibrary
picker.mediaTypes = [kUTTypeMovie as String]
picker.allowsEditing = true
self.present(picker, animated: true, completion: nil)
}
#objc func photoPresentPicker() {
self.croppingStyle = .default
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .photoLibrary
picker.allowsEditing = false
self.present(picker, animated: true, completion: nil)
}
I am truly appreciated for you help. I have been struggling for few days and finally reaching out for some helps...
Update
extension ChatViewController: CropViewControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
internal func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let videoUrl = info[UIImagePickerController.InfoKey.mediaURL] as? NSURL {
let data = NSData(contentsOf: videoUrl as URL)!
print("File size before compression: \(Double(data.length / 1048576)) mb")
let compressedURL = NSURL.fileURL(withPath: NSTemporaryDirectory() + NSUUID().uuidString + ".m4v")
self.compressVideo(inputURL: videoUrl as URL, outputURL: compressedURL) { (exportSession) in
guard let session = exportSession else {
return
}
switch session.status {
case .unknown:
break
case .waiting:
break
case .exporting:
break
case .completed:
guard let compressedData = NSData(contentsOf: compressedURL) else {
return
}
print("File size after compression: \(Double(compressedData.length / 1048576)) mb")
case .failed:
break
case .cancelled:
break
#unknown default:
break
}
}
} else {
guard let image = (info[UIImagePickerController.InfoKey.originalImage] as? UIImage) else { return }
let cropController = CropViewController(croppingStyle: croppingStyle, image: image)
cropController.delegate = self
imageView.image = image
picker.dismiss(animated: true, completion: {
self.present(cropController, animated: true, completion: nil)
if self.inputTextField.isFirstResponder == true {
self.handleKeyboardWillShow()
}
})
}
transparentView.alpha = 0
self.tableView.frame = CGRect(x: 0, y: 0, width: 0, height: 0)
dismiss(animated: true, completion: nil)
}
Just implement this function
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated:true, completion: nil)
}

Save user profile picture to firebase

Good Afternoon, I am trying to allow users to save their profile picture in firebase. my application runs without a crash. however, when I select a picture it doesn't save to the system. I have a ViewController, and an extension file that I have been placing my code in. I will place below. Please help me understand what I am doing wrong. Hopefully, this question will help others who are facing the same issues.
import UIKit
import Firebase
class EditProfileVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupProfileImageView()
self.view.backgroundColor = UIColor.white
}
func setupProfileImageView() {
view.addSubview(profileImageView)
profileImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
profileImageView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100).isActive=true
profileImageView.widthAnchor.constraint(equalToConstant: 120).isActive = true
profileImageView.heightAnchor.constraint(equalToConstant: 120).isActive = true
profileImageView.layer.cornerRadius = 60
profileImageView.layer.masksToBounds = true
var randomString = UUID().uuidString
let storageRef = Storage.storage().reference().child;"\(randomString).png")
if let uploadImage = UIImagePNGRepresentation(self.profileImageView.image!) {
storageRef.putData(uploadImage, metadata: nil) { (metadata, error) in
if error != nil {
print("Error upload data to Firebase Storage. Detail: \(String(describing: error))")
return
}
if let profileImageURl = metadata?.downloadURL()?.absoluteString {
self.registerUser(UserId: userId, profileImageURL: profileImageURL) {
}
}
}
}
}
lazy var profileImageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "users")
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFill
imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleSelectProfileImageView)))
imageView.isUserInteractionEnabled = true
return imageView
}()
}
// This is my extension file
import UIKit
import Firebase
extension EditProfileVC: UIImagePickerControllerDelegate, UINavigationControllerDelegate{
#objc func handleSelectProfileImageView() {
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true
present(picker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var selectedImageFromPicker: UIImage?
dismiss(animated: true, completion: nil)
if let editedImage = info["UIImagePickerControllerEditedImage"] {
selectedImageFromPicker = editedImage as? UIImage
} else if let originalImage = info["UIImagePickerControllerOriginalImage"] {
selectedImageFromPicker = originalImage as? UIImage
}
if let selectedImage = selectedImageFromPicker {
profileImageView.image = selectedImage
}
print(info)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print("Canceled Picker")
dismiss(animated: true, completion: nil)
}
}
My app doesn't crash when I run it. It's just no images are stored in firebase. I want users to click onto the EditProfileVC, then be able to change their profile picture and have it save. If anyone can help me solve this issue, it would be greatly appreciated.

Swift: CoreData load my image (portrait) at 90 degrees

When I save, my image to coreData, when I re-open it from CoreData, all image who was took in portrait, are in landscape orientation.
I fund lot of previews question a bout it but all in Objective C not in Swift.
How can I fix the problem?
This is my code: ( it is also a text application when it work I will add it to my project)
This text app has two image view one for loading from library and one for loading from coreData.
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate{
var monimage: String!
let imagePicker = UIImagePickerController()
#IBOutlet weak var MaPhoto: UIImageView? = UIImageView()
#IBOutlet weak var maPhoto2: UIImageView! = UIImageView()
var cameraUI:UIImagePickerController = UIImagePickerController()
var yourContacts:NSMutableArray = NSMutableArray()
override func viewDidLoad() {
imagePicker.delegate = self
super.viewDidLoad()
}
#IBAction func LabraryImage(sender: AnyObject) {
imagePicker.delegate = self
imagePicker.sourceType = .PhotoLibrary
imagePicker.allowsEditing = true
presentViewController(imagePicker, animated: true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
#IBAction func takePhoto(sender: UIButton) {
if (UIImagePickerController.isSourceTypeAvailable(.Camera)){
cameraUI = UIImagePickerController()
cameraUI.delegate = self
cameraUI.sourceType = UIImagePickerControllerSourceType.Camera
cameraUI.allowsEditing = true
self.presentViewController(cameraUI, animated: true, completion: nil)
}else{
//no camera available
let alert = UIAlertController(title: "Error", message: "There is no camera available", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Okay", style: .Default, handler: {(alertAction)in
alert.dismissViewControllerAnimated (true, completion: nil)
}))
}
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
MaPhoto!.contentMode = .ScaleAspectFit
MaPhoto!.image = pickedImage
}
dismissViewControllerAnimated(true, completion: nil)
}
#IBAction func btnSavePressed(sender : AnyObject) {
let appDel:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context:NSManagedObjectContext = appDel.managedObjectContext!
let ent = NSEntityDescription.entityForName("ImageData", inManagedObjectContext: context)
var newUser = ImageData (entity: ent!, insertIntoManagedObjectContext: context)
let contactImageData:NSData = UIImagePNGRepresentation(MaPhoto!.image)
newUser.monimage = contactImageData
context.save(nil)
self.navigationController?.popViewControllerAnimated(true)
}
#IBAction func loadImage(sender: AnyObject){
let appDel:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context:NSManagedObjectContext = appDel.managedObjectContext!
let request2 = NSFetchRequest (entityName: "ImageData")
request2.returnsObjectsAsFaults = false;
var results2:NSArray = context.executeFetchRequest(request2, error: nil)!
if results2.count > 0 {
for user in results2{
var thisUser2 = user as! ImageData
let profileImage:UIImage = UIImage(data: thisUser2.monimage)!
maPhoto2.image = profileImage
}
}
}
I also working to get the image square so it is for that "allowEditing is = true"
Thank s for your help!
this is the answer to my question:
#IBAction func btnSavePressed(sender : AnyObject) {
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
let entity = NSEntityDescription.entityForName("ImageData",
inManagedObjectContext: managedContext)
let options = NSManagedObject(entity: entity!,
insertIntoManagedObjectContext:managedContext)
var newImageData = UIImageJPEGRepresentation(MaPhoto!.image,1)
options.setValue(newImageData, forKey: "monimage")
var error: NSError?
managedContext.save(&error)
}
JPGs are great for photos. However, saving in jpeg might loose some quality which png tends to excel as it has a lossless compression format.
Its just a matter of preference and what you need at the moment. If you don't want to convert to jpg you can call this method then convert to pngData to preserve orientation before saving to coreData. :)
func rotatedCopy() -> UIImage {
if self.imageOrientation == UIImage.Orientation.up {
return self
}
UIGraphicsBeginImageContext(size)
//draws the image in current context respecting orientation
draw(in: CGRect(origin: CGPoint.zero, size: size))
let copy = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return copy!
}