Image being rotated when user picks one from photo gallery - ios

I'm currently making an app where one of the views allows the user to take a pic of their schedule from their photo library and it would be saved in the app. The saving feature works fine. However, when the user selects an image, it is rotated 90 degrees. For example, a portrait picture would be rotated and resized which makes it hard to read. How can I disable the rotating feature?
import UIKit
class Schedule: UIViewController, UIImagePickerControllerDelegate,
UINavigationControllerDelegate {
#IBOutlet var imageView: UIImageView!
let imagePicker = UIImagePickerController()
#IBAction func addImage(sender: AnyObject) {
imagePicker.allowsEditing = false
// Only allow photos to be picked, not taken.
imagePicker.sourceType = .PhotoLibrary
presentViewController(imagePicker, animated: true, completion: nil)
}
// User picks image
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.contentMode = .ScaleAspectFit
imageView.image = pickedImage
let data = UIImagePNGRepresentation(pickedImage)
NSUserDefaults.standardUserDefaults().setObject(data, forKey: "image")
NSUserDefaults.standardUserDefaults().synchronize()
}
dismissViewControllerAnimated(true, completion: nil)
}
// User cancels picking image action
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
if let imageData = NSUserDefaults.standardUserDefaults().objectForKey("image") as? NSData {
self.imageView.image = UIImage(data: imageData)
}
}
}

That's a common behaviour, you can see that even in apps like Whatsapp and others.
The reason why you see it right in the Photos app is because they use the information of the sensors to determine what's the correct orientation.
You can prove this by copying the photos from iPhone to a Windows PC, you will see not all the photos are in the correct orientation.
I'm not sure if you can access those metadata to determine it yourself.
At least Whatsapp uses a button to rotate the images as requested by the user, that could be a temporary solution.

Related

IOS Firebase storage file upload - object does not exist

I'm trying to use Firebase on IOS (Swift) to upload an image file chosen by the user to the firebase storage.
I've already authenticated the user, so that is not the problem.
Below you can see the view controller that I'm trying to use, but when it tries to upload the image, I get back an error message saying:
Object images/vesVLmkqS2cCLQTJOjv9CFe8mh22/0524729A-855E-4E63-8C11-50F4C4B1A905 does not exist.
(you can see in the code that the middle part of this path is the user uid, so I definitely have an authenticated user)
I tried to simplify this path before to test value like "myimage.png" but didn't help, I got the same error.
I've already tried everything I could, please help me because I can't find anything related in the firebase documentation.
The code below automatically opens the image picker when the view loads. If the user chooses an image, we set it to an image view. When the user clicks the upload button, the controller tries to upload the file to firebase storage.
import UIKit
import Firebase
class ShareViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var imageView: UIImageView!
let imagePicker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
imagePicker.allowsEditing = false
imagePicker.sourceType = .photoLibrary
present(imagePicker, animated: true, completion: nil)
}
#IBAction func onPictureTapped(_ sender: Any) {
present(imagePicker, animated: true, completion: nil)
}
#IBAction func onUploadClicked(_ sender: Any) {
if let pickedImage = imageView.image, let imageData = UIImagePNGRepresentation(pickedImage) {
let storageRef = Storage().reference()
let imageRef = storageRef.child("images/\(Auth.auth().currentUser!.uid)/\(NSUUID().uuidString)")
imageRef.putData(imageData, metadata: nil) { (metadata, error) in
if error != nil {
NSLog(error!.localizedDescription)
}
self.navigationController?.popToRootViewController(animated: true)
}
}
}
internal func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.contentMode = .scaleAspectFit
imageView.image = pickedImage
}
self.dismiss(animated: true, completion: nil)
}
}
Ok, I found the problem:
// Instead of this:
Storage().reference()
// You need to use this
Storage.storage().reference()
This is ridiculous that there are no warnings about this, also the app don't crash. Very annoying, and it took me at least 5 hours to find

How to save image to internal memory of app after taking it by camera

I'm developing an app in which I prompt the user to take a picture with his phone and then I put this picture to my imageViewbut I want to save that picture to have it after the user restart the application.
Here is my code:
var imagePicker: UIImagePickerController!
//MARK: - Take image
#IBAction func takePhoto(_ sender: UIButton) {
imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .camera
present(imagePicker, animated: true, completion: nil)
}
//MARK: - Done image capture here
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
imagePicker.dismiss(animated: true, completion: nil)
imageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage
}
With above code I take the picture and put it in my imageView but I don't know how can I save it for example in UserDefaults
Use this code -
Save image -
UserDefaults.standard.set(UIImagePNGRepresentation(image), forKey: "image")
Retrieve image -
let imageData: Data? = UserDefaults.standard.object(forKey: "image") as? Data
if let imageData = imageData
{
var image = UIImage(data: imageData)
}

Swift 3 - How do I use a photolibrary picture in an app?

How can I use a picture from the Photo Library in my app? I have done the tutorials about credating a photo app. That all works fine. I have a UIPickerController, can take a picture with the camera, save it to the library, or select an image from the library, which is then put onto the screen. But...
What I want is that the user selects a picture, remember the name of the picture or the number or something, and then on another page use this picture from the library.
Like selecting an avatar. Saving the picture somewhere and whenever the user enters the profile page, open up this avatar picture previously selected. So what I need is the "name"(represenation) of the picture, but I can't find that. How do I do that?
(the code below is just the working cam/lib app part, but it saves the picture without name, that's the problem: How do I find out what picture was saved earlier?) P.S. Sorry, variable names are in Dutch.
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var plaatje: UIImageView!
#IBAction func saveknop(_ sender: UIButton) {
let imageData = UIImageJPEGRepresentation(plaatje.image!, 0.6)
let compressedfoto = UIImage(data: imageData!)
UIImageWriteToSavedPhotosAlbum(compressedfoto!, nil, nil, nil)
saveNotice()
}
#IBAction func cameraknop(_ sender: UIButton) {
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)
}
}
#IBAction func biepknop(_ sender: Any) {
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)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
plaatje.image = image
self.dismiss(animated: true, completion: nil)
}
func saveNotice() {
let alert = UIAlertController(title: "foto genomen", message: "je foto is bewaard in de biep", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(defaultAction)
present(alert, animated: true, completion: nil)
}
}
One solution I found is to use UIImageJPEGRepresentation or UIImagePNGRepresentation to convert the image into a Data object. From there you can use the write(to:) method to save it to the specific URL you want your app to use.
The answer to this SO question shows a few ways to store the image. It might be of help.
I had the same trouble earlier, this did the trick for me:
Save images using the following method:
func saveImage(image: UIImage, path: String ) {
let pngImageData = UIImagePNGRepresentation(image)
do {
try pngImageData?.write(to: URL(fileURLWithPath: path), options: .atomic)
} catch {
print(error)
}
}
Load saved images using:
func loadImageFromName(name: String) -> UIImage? {
let path = self.fileInDocumentsDirectory(filename: name)
let image = UIImage(contentsOfFile: path)
if image == nil {
print("Image not available at: \(path)")
}
return image
}
func fileInDocumentsDirectory(filename: String) -> String {
let documentsFolderPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)[0] as NSString
return documentsFolderPath.appendingPathComponent(filename)
}
Call the save method like this:
saveImage(image: image, path: fileInDocumentsDirectory(filename: "someId"))
Good luck! Hope this helps.
Struggeling with the suggestions, I found another solution, that is strangely simple. But it works! Weird. It is not the best one, but for now I'll use this, untill I understand everyuthiong about the directorys and filesystem on the iphone.
P.S. credit goes to: http://theswiftguy.com/index.php/2016/11/10/how-to-save-an-image-locally-in-xcode-8-swift-3-0/
//Encoding
let image = UIImage(named: "dog.png")
let imageData:NSData = UIImagePNGRepresentation(image!)! as NSData
//Saved image
UserDefaults.standard.set(imageData, forKey: "savedImage")
//Decode
let data = UserDefaults.standard.object(forKey: "savedImage") as! NSData
myImageView.image = UIImage(data: data as Data)

Saving ImageView content in memory? What is the best approach?

I've been looking for this answer online all morning long and I didn't find exactly what I needed. I want the user to add an image from his library and it would appear on the screen. I've managed to write the code that allows me to do that. However, I want that image to be saved. By that, I mean that I want the image selected to still appear after the user closes the app and reopens it. How can I do that?
Any help would be really appreciated :)
I've attached my code:
import UIKit
class Schedule: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var imageView: UIImageView!
let imagePicker = UIImagePickerController()
#IBAction func addImage(sender: AnyObject) {
imagePicker.allowsEditing = false
// Only allow photos to be picked, not taken.
imagePicker.sourceType = .PhotoLibrary
presentViewController(imagePicker, animated: true, completion: nil)
}
// User picks image
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.contentMode = .ScaleAspectFit
imageView.image = pickedImage
}
dismissViewControllerAnimated(true, completion: nil)
}
// User cancels picking image action
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
}
}
You can do this using NSUserDefault, It will store your image data and you can retrieve it later. Change your viewDidLoad like this
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
if let imageData = NSUserDefaults.standardUserDefaults().objectForKey("image") as? NSData {
self.imageView.image = UIImage(data: imageData)
}
}
Now you need to store this imageData in NSUserDefault when you select image from UIImagePicker
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.contentMode = .ScaleAspectFit
imageView.image = pickedImage
let data = UIImagePNGRepresentation(pickedImage)
NSUserDefaults.standardUserDefaults().setObject(data, forKey: "image")
NSUserDefaults.standardUserDefaults().synchronize()
}
dismissViewControllerAnimated(true, completion: nil)
}
Hope this will help you.

UIImagePickerController get Image URL with Swift

I have a UIImagePickerController to let the user select a image, as i want to upload this image i would need the image "localURL".
Is there a way to get this localURL from my picker.
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
}
#IBAction func loadImageButtonTapped(sender: AnyObject) {
imagePicker.allowsEditing = false
imagePicker.sourceType = .PhotoLibrary
presentViewController(imagePicker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.contentMode = .ScaleAspectFit
imageView.image = pickedImage
}
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
You won't get any local url since you don't have access to images outside of your app container.
You don't need the file for transmitting the image, NSData should be perfectly fine. I suggest you transform it to NSData like this
let imageData: NSData = UIImagePNGRepresentation(pickedImage)
Update: as i said, you won't have access to the actual file. The only way to have the image as file is to store it yourself.
in your update you showed some code for persisting the image yourself, which makes sense. It will be more performant if you use the ’pickedImage’ when setting your ’imageView.image’ instead of writing the image file and reading it, transforming it to an ’UIImage’ and then setting it as ’imageView.image’
I still havent really figured out, why you need the image as file and not simply send the ’NSData’ to your server. Maybe that is an option worth considering for you
as work around i do save the image,
if let data = UIImageJPEGRepresentation(pickedImage, 0.8) {
let filename = getDocumentsDirectory().stringByAppendingPathComponent("image.jpg")
data.writeToFile(filename, atomically: true)
print("file saved as image.jpg")
print(filename)
var image = UIImage(contentsOfFile: filename)
imageView.image = image
}

Resources