I am trying to get an image that I have stored inside Firebase Storage inside an UIImageView.
I have the URL of the image saved inside Firebase Database for that user, but don't know how to grab it
you need to make an action for it this func opens the Photo carrier
#IBAction func selecFoto(_ sender: UIButton) {
let imageController = UIImagePickerController()
imageController.delegate = self
imageController.sourceType = UIImagePickerController.SourceType.photoLibrary
//you can also set animate to false
self.present(imageController, animated: true, completion: nil)
}
this func selects the image and you can storage wherever you want
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// here you can preview the image you selected if that's the case
imageView.image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
self.dismiss(animated: true, completion: nil)
}
import FirebaseStorage
Storage.storage().reference(forURL: yourDownloadedURL).getData(maxSize: 1048576, completion: { (data, error) in
guard let imageData = data, error == nil else {
return
}
someImageView.image = UIImage(data: imageData)
})
Obviously, handle errors as well as corrupted image data, by perhaps falling back to a default image (just because we have image data in hand does not guarantee it will render a perfect image), and use a maximum file size appropriate to your application.
Related
I'm trying to get this working code that retrieves the UIImage via the selectedImage from the ImagePicker and saves it via the savePhoto method, to ALSO get me the metadata of the UImage:
Original Code:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]){
if let selectedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
//Successfully got the image, now upload it
//Get a reference to the camera view controller and call the savePhoto method
let cameraVC = self.selectedViewController as? CameraViewController
if let cameraVC = cameraVC {
cameraVC.savePhoto(image: selectedImage)
}
//Dismiss the picker
picker.dismiss(animated: true, completion: nil)
}
}
This is what I tried but thisAsset always comes back nil so it skips over basically the entire method.
Code I tried:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]){
var arrImageIdentifiers = String()
if let thisAsset:PHAsset = info[UIImagePickerController.InfoKey.phAsset] as? PHAsset {
arrImageIdentifiers.append(thisAsset.localIdentifier)
//Get a reference to the camera view controller and call the savePhoto method
let cameraVC = self.selectedViewController as? CameraViewController
let manager = PHImageManager.default()
manager.requestImage(for: thisAsset, targetSize: CGSize(width: 300.0, height: 300.0), contentMode: .aspectFit, options: nil, resultHandler: {(thisImage, _) in
if let cameraVC = cameraVC {
cameraVC.savePhoto(image: thisImage!)
}
})
}
self.dismiss(animated: true, completion: nil)
}}
What's the easiest way to get the photo metadata (creationDate, location, etc) from the original code above?
The image you get from your first code does not include the metadata. Your second code is closer to being correct; you need to go back to the PHAsset and pick up the metadata from the photo library.
This is what I tried but thisAsset always comes back nil
Because you forgot to get user authorization for the photo library. Without that, you cannot access the PHAsset.
extension PHAsset {
func metadata(_ completion: #escaping (String?) -> Void) {
let options = PHContentEditingInputRequestOptions()
options.isNetworkAccessAllowed = true
requestContentEditingInput(with: options) { input, _ in
guard let url = input?.fullSizeImageURL,
let image = CIImage(contentsOf: url)
else {
completion(nil)
return
}
let properties = image.properties
let tiffDict = properties["{TIFF}"] as? [String: Any]
let make = tiffDict?["Make"] as? String ?? ""
completion(make)
}
}
}
asset.metadata { metadata in
guard let metadata = metadata else {
return
}
// You can explore all available metadata values here.
}
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
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)
}
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.
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
}