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

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.

Related

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)
}

Image being rotated when user picks one from photo gallery

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.

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
}

UIImageView not updating image

I am trying to make a simple "Profile" view that allows the user to change his picture. the image picker loads the gallery successfully and i choose the new image then write it to documents directory to load it in next launch, the problem is the imageview is not refreshing with the new image until i exit the app and relaunch again (only viewDidLoad works but viewWillAppear is loading the old image although it is overwritten!) any ideas?
import UIKit
class Profile: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
var imagePicker:UIImagePickerController=UIImagePickerController()
var pickedImage:UIImage?
let filemgr = NSFileManager.defaultManager()
#IBOutlet weak var profilepic: UIImageView!
#IBOutlet weak var lblheight: UILabel!
#IBOutlet weak var lblwidth: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
profilepic.layer.borderWidth=1
profilepic.layer.borderColor=UIColor.blackColor().CGColor
let tapGestureRecognizer = UITapGestureRecognizer(target:self, action:Selector("imageTapped:"))
profilepic.userInteractionEnabled = true
profilepic.addGestureRecognizer(tapGestureRecognizer)
imagePicker.delegate=self
if profileImageExists()
{
pickedImage=UIImage(named: Operations.getDocumentsDirectory().stringByAppendingPathComponent("profile.png"))!
} else {
pickedImage=UIImage(named:"camera.png")!
}
profilepic.image=pickedImage
}
func imageTapped(img: AnyObject)
{
imagePicker.allowsEditing = false
imagePicker.sourceType = .PhotoLibrary
presentViewController(imagePicker, animated: true, completion:
{
self.lblheight.text="completed"
print ("completed image tab")
}
)
}
override func viewWillAppear(animated: Bool) {
pickedImage=UIImage(named: Operations.getDocumentsDirectory().stringByAppendingPathComponent("profile.png"))!
profilepic.image=pickedImage
}
// MARK: - UIImagePickerControllerDelegate Methods
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
profilepic.contentMode = .ScaleToFill
profilepic.image = pickedImage
if let data = UIImagePNGRepresentation(pickedImage) {
let filename = Operations.getDocumentsDirectory().stringByAppendingPathComponent("profile.png")
data.writeToFile(filename, atomically: true)
}
}
dismissViewControllerAnimated(true, completion: nil)
}
func profileImageExists() -> Bool
{
if let profileImage=UIImage(named: Operations.getDocumentsDirectory().stringByAppendingPathComponent("profile.png"))
{
return true
}
else
{
return false
}
}
}
Loading an UIImage with init(named:) caches the image. So as long as the image name does not change or the system is emptying the cache (for example when you restart the app) the image will be used from the cache and not loaded again.
Try to use init(contentsOfFile:) instead to load the image.
Try updating your imagePickerController method. You have used pickedImage as an instance variable and an local optional variable. I have used newImage instead.
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let newImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
profilepic.contentMode = .ScaleToFill
profilepic.image = newImage
pickedImage = newImage
if let data = UIImagePNGRepresentation(newImage) {
let filename = Operations.getDocumentsDirectory().stringByAppendingPathComponent("profile.png")
data.writeToFile(filename, atomically: true)
}
}
dismissViewControllerAnimated(true, completion: nil)
}

Three images using image picker

I am building an app that allows user to add three pictures to threeUIImageViews
I added three buttons, for instance, when a user clicks on button one he should be able to add an image toUIImageView 1
but the image did not come to theUIImageView and I did not find any solution
sample of code:
#IBAction func imageOneBtn(sender: AnyObject) {
picker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
picker.delegate = self
picker.allowsEditing = false
self.presentViewController(picker, animated: true, completion: nil)
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]){
let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
imageViewOne.image = selectedImage
imageViewOne.contentMode = UIViewContentMode.ScaleAspectFit
picker.dismissViewControllerAnimated(true, completion: nil)
}
}
Thank you in advance
The code seems to be correct.
let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
Try removing the exclamation mark (!).
Try using imageViewOne.contentMode = .ScaleAspectFit
Also try using var instead of let selectedImage
In general Try this code
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
var selectedImage = info[UIImagePickerControllerOriginalImage] as UIImage
imageViewOne.contentMode = .ScaleAspectFit
imageViewOne.image = selectedImage
dismissViewControllerAnimated(true, completion: nil)
}
I have solved my problem, and this is the answer for anyone who may want to use it
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var oneImg: UIImageView!
#IBOutlet weak var twoImg: UIImageView!
#IBOutlet weak var threeImg: UIImageView!
var num=0;
func config() {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.allowsEditing = true
imagePickerController.sourceType = .PhotoLibrary
presentViewController(imagePickerController, animated: true, completion: nil)
}
#IBAction func oneBtn(sender: AnyObject) {
num = 1
config()
}
#IBAction func twoBtn(sender: AnyObject) {
num = 2
config()
}
#IBAction func threeBtn(sender: AnyObject) {
num = 3
config()
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]){
let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage;
if num == 1 { // switch can be used here
oneImg.image = selectedImage;
} else if (num == 2) {
twoImg.image = selectedImage
} else if (num == 3) {
threeImg.image = selectedImage
}
picker.dismissViewControllerAnimated(true, completion: nil)
}
}

Resources