Set UImage form local path URL - causes crash - ios

Setting imageviews in collection view with local path URL like this:
let fileURL = documentsUrl.appendingPathComponent(fileName)
myImageView.image = UIImage(named: fileURL.path)
Causes crash - images are high quality - tried to reduce size also - still crashes the app with no error message.

func getDirectoryPath() -> String {
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = paths[0]
return documentsDirectory
}
let imagePath = (getDirectoryPath() as NSString).appendingPathComponent("/\(file_name).jpg")
let myImageView.image = UIImage(contentsOfFile: imagePath)!

If the image is in the bundle (included with the app), you don't pass the whole path to UIImage(named: ...), only the filename. So your call would be UIImage(named: fileName)
If you have the image in the documents path (you downloaded it from the app) use UIImage(contentsOfFile: fileURL.path)

Related

Storing and retrieving image using path to stored file as String

I'm using Realm and storing the file path to captured images as Strings. I want to retrieve them later for use in a tableView. Here's my code to store the path for each image:
func saveImage(imageName: String){
//create an instance of the FileManager
let fileManager = FileManager.default
//get the image path
thisImagePath = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent(imageName)
//get the image taken with camera
let image = originalCapturedImage
//get the PNG data for this image
let data = UIImagePNGRepresentation(image!)
//store it in the document directory
fileManager.createFile(atPath: thisImagePath as String, contents: data, attributes: nil)
print("Picture path at assignment \n")
print(thisImagePath as Any)
}
And here's the code to retrieve the image:
...
var paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsPath = paths[0] //Get the docs directory
let filePath = URL(fileURLWithPath: documentsPath).appendingPathComponent(item.picPath).path
let image = UIImage(contentsOfFile: filePath)
print("Picture path at retrieval \n")
print(item.picPath as Any)
cell.imageWell.image = image
cell.imageWell.clipsToBounds = true
return cell
}
Here's the comparison of the file path at runtime:
Picture path at assignment
/var/mobile/Containers/Data/Application/0E9CACAD-C6B3-4F6C-B0DB-72C43AC722E1/Documents/1535219147
...
...
Picture path at retrieval
/var/mobile/Containers/Data/Application/0E9CACAD-C6B3-4F6C-B0DB-72C43AC722E1/Documents/1535219147
The paths appear identical to me, yet no image appears. I've searched all over SO, and at one point came across a mention of the use of the URL for the file path. Somehow, I lost track of that entry and haven't been able to find it again.
Any help would be greatly appreciated!
You can try with below code for writing the image to the file instead of creating file with content. try? data.write(to: URL(fileURLWithPath: documentsPath))
You can also refer below code for saving image.
class func saveImageToFileWithDirectory(_ imageData:Data, fileName:String, folderName : String? = nil) {
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as NSArray
let documentsDirectory = paths.object(at: 0) as! NSString
let path = documentsDirectory.appendingPathComponent(folderName) as NSString
if !FileManager.default.fileExists(atPath: path as String) {
do {
try FileManager.default.createDirectory(atPath: path as String, withIntermediateDirectories: true, attributes: nil)
} catch let error as NSError {
print(error.localizedDescription);
}
}
let imagePath = path.appendingPathComponent(fileName)
if !FileManager.default.fileExists(atPath: imagePath as String) {
try? imageData.write(to: URL(fileURLWithPath: imagePath))
} }
Code for retrieving the image looks good. If you need help in that also, pls comment, I will post that also.
Hope this solves your issue.

UIImage from path or filename in Swift 3

i have a bunch of images in my App's Documents Directory. i want to load one of them in an UIImage that i have in my view. this is what i do:
myImage.image = UIImage(named: "image.jpg") // the file exist but this returns nil
I also tried to init the image using:
myImage.image = UIImage(contentsOfFile: imagePath) //this also doesn't work but the path i got starts (at least in the sim) with file://
Anyone can suggest something? I'm kinda a noob in iOS programming.
Thanks
EDIT:
imagePath comes from:
func getImgPath(name: String) -> String
{
let documentsDirectory = self.getDocumentsDirectory()
let fullpath = documentsDirectory.appendingPathComponent(name)
return fullpath.absoluteString
}
This might help
let documentDirectory = FileManager.SearchPathDirectory.documentDirectory
let userDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(documentDirectory, userDomainMask, true)
if let dirPath = paths.first
{
let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent("name.png")
let image = UIImage(contentsOfFile: imageURL.path)
// Do whatever you want with the image
}
Try adding your images under Assets.xcassets. Then you'll be able to reference your image by:
UIImage(named: 'yourImageName')
You can conveniently add images with various size settings.
You can get the path of the image as fowllows:
let imagePath = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("image.jpg")
If this doesn't work, check if your file name is correct.
I understand that if you are downloading images from internet means, you need to convert the URL to UIImage
if let url = URL(string: "your url") {
let data = try? Data(contentsOf: url)
if let imageData = data {
if let image = UIImage(data: imageData) {
imageView.image = image
}
}
}
If i understand your question correct, this will be the answer.

Get image from local URL (iOS)

I am getting a photo's URL using requestContentEditingInput using the PHLibrary
asset.requestContentEditingInput(with: PHContentEditingInputRequestOptions()) { (input, _) in
let url = input?.fullSizeImageURL
}
This URL prints: file:///Users/josh/Library/Developer/CoreSimulator/Devices/EE65D986-55E7-414C-A73E-D1C96FF17004/data/Media/DCIM/100APPLE/IMG_0005.JPG.
How do I retrieve this image? I've tried the following but it does not return anything:
var fileLocation = "file:///Users/josh/Library/Developer/CoreSimulator/Devices/EE65D986-55E7-414C-A73E-D1C96FF17004/data/Media/DCIM/100APPLE/IMG_0005.JPG"
let url = URL(string: fileLocation)
let asset = PHAsset.fetchAssets(withALAssetURLs: [url!], options: nil)
if let result = asset.firstObject {
//asset.firstObject does not exist
}
apparently apple will not allow the developer to access any and every photo in the user's photo library even after they have accepted photos usage. If you are using an image that hasnt been picked from the imagePicker, (i.e. choosing last image in library), you have to store the image in the document directory before you can use the document directory URL. I guess this prevents people hacking into others photo library
//Storing the image (in my case, when selecting last photo NOT via imagePicker)
let fileManager = FileManager.default
let paths = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("image01.jpg")
let imageData = UIImageJPEGRepresentation(image!, 1.0)
fileManager.createFile(atPath: paths as String, contents: imageData, attributes: nil)
//Retrieving the image
let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
if let dirPath = paths.first {
let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent("image01.jpg")
if let imageRetrieved = UIImage(contentsOfFile: imageURL.path) {
//do whatever you want with this image
print(imageRetrieved)
}
}

Problems with loading image path from realm in Swift

In my app I am storing an image in local storage and I am saving the path of that image in my Realm database. And now i have problems with load this image from that path?
Thats how I save path to database:
let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory,nsUserDomainMask, true)
let dirPath = paths.first
let imageURL1 = URL(fileURLWithPath: dirPath!).appendingPathComponent("refuge1.jpg")
let med1 = Meditation()
med1.name = "Refuge"
med1.count = 0
med1.targetAmount = 111111
med1.malasStep = 108
med1.imagePath = imageURL1.path
med1.id = 1
It's straightforward that am trying to get an image from this meditation.imagePath path. I double-checked the path, image is there still am not able to set the image using this path, is there is something that am missing?
In debug mode I see this:
Meditation {
name = Refuge;
count = 0;
targetAmount = 111111;
malasStep = 108;
imagePath = /Users/macbook/Library/Developer/CoreSimulator/Devices/2E25309F-D6A9-41C3-9EF4-67203142172C/data/Containers/Data/Application/F198640B-3C72-4F9C-8173-FB00D3ABEC15/Documents/refuge1.jpg;
id = 1;}
but my variable image still nil in debug mode
// Configure the cell...
cell.nameOfMeditation.text = meditation.name
cell.countOfMeditation.text = String(meditation.count)
let image = UIImage(contentsOfFile: meditation.imagePath)
cell.imageForMeditation.image = image
return cell
I see name of meditation and sound, bot no omg.
It's not advised to save the absolute file path of a file in an iOS app (ie, everything including /Users/macbook/Library/Developer/...), in Realm or anywhere else.
For security reasons, iOS devices rename the UUID folder name between launches. This means that while the folder path was valid at the time it was saved, it won't be at a later date.
Instead, it's recommended to save just the relative path of the file (eg, its location in relation to just the Documents folder. In this case, it would be just /refuge1.jpg) and to then dynamically build the absolute path by requesting the Documents directory path as you need it.
Try this:
// Use these convenience methods if you do a lot of saving and loading
func getDocumentsURL() -> URL {
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
return documentsURL
}
func fileInDocumentsDirectory(_ filename: String) -> String {
let fileURL = getDocumentsURL().appendingPathComponent(filename)
return fileURL.path
}
func saveRefugeOne(image: UIImage) {
// Create a file name, and then save the path in your documents with that name
let imageFileName:String = "refuge1.jpg"
let imagePath = fileInDocumentsDirectory(imageFileName!)
saveImage(image, path: imagePath)
}
func loadRefugeOne() -> UIImage? {
// Get the image back
let imageName:String = "refuge1.jpg" // Or whatever name you saved
let imagePath = fileInDocumentsDirectory(imageName)
if let loadedImage = self.loadImageFromPath(imagePath) {
return loadedImage
} else {
print("Couldn't Load: \(imageName)")
return nil
}
}
// This will be your method to save image
func saveImage(_ image: UIImage, path: String ) {
//If you want PNG use this let pngImageData = UIImagePNGRepresentation(image)
// But since you mentioned JPEG:
if let jpgData = UIImageJPEGRepresentation(image, 1.0) {
try? jpgData.write(to: URL(fileURLWithPath: path), options: [.atomic])
}
}
// This will load image from saved path. Make sure to store the path
// somewhere. This makes it easier to save images locally. You can
// save the image in the documents directory, and then just save the
// path in CoreData or something similar.
func loadImageFromPath(_ path: String) -> UIImage? {
let image = UIImage(contentsOfFile: path)
if image == nil {
print("couldn't find image at path: \(path)")
}
return image
}
Hopefully this will help. It's the method I always use, and it works like a charm when I follow my own steps right ;-)

Load image form Gallery in swift from path given by UIImagePickerViewController?

I am saving path in Database return by UIImagepicker from Gallery
let imageURL = info[UIImagePickerControllerReferenceURL] as! NSURL
let imageName = imageURL.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first! as String
//let localPath = documentDirectory.stringByAppendingPathComponent(imageName!)
let imagePath = String("\(documentDirectory)/\(imageName!)")
where path look like
/Users/kshitijghule/Library/Developer/CoreSimulator/Devices/3AC7B500-E980-4A00-BC32-34FA3C7DDE8A/data/Containers/Data/Application/838FB5A1-4448-46C9-8BEC-2E939668B97D/Documents/asset.JPG
Now i want load this image from this path.
i used this code
let url = NSURL(string:"/Users/kshitijghule/Library/Developer/CoreSimulator/Devices/3AC7B500-E980-4A00-BC32-34FA3C7DDE8A/data/Containers/Data/Application/838FB5A1-4448-46C9-8BEC-2E939668B97D/Documents/asset.JPG")!//path from database but mention static
let imageData = NSData(contentsOfURL:url)!
cell?.petImageView.image = UIImage(data: imageData)
But i am getting crash at line
let imageData = NSData(contentsOfURL:url)!
How to fix this issue? It will work on device ?
If you are storing images in the document directory store only image name in the db
At the time of retrieval append the current document directory path with your image name like you done at save time
let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first! as String
//let localPath = documentDirectory.stringByAppendingPathComponent(imageName!)
//imageName which you have stored in the db at retrieval time
let imagePath = String("\(documentDirectory)/\(imageName!)")
let url = NSURL(string:imagePath)
let imageData = NSData(contentsOfURL:url)!
as i have also this type of issue at last if found that the app number of simulator(838FB5A1-4448-46C9-8BEC-2E939668B97D) is changes which cause the issue
Hope this may solve your issue
I have answered a similar question here.You only have to save those paths to your database, and from the database path you can retrieve those images.
Save image in Document Directory taken from Gallery or Camera.
func origionalImage(origionalImage: UIImage!, editedImage: UIImage!, userInfo info: [NSObject : AnyObject]!) {
let imageData = NSData(data:UIImagePNGRepresentation(origionalImage)!)
let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let docs: String = paths[0]
let imageName = self.randomStringWithLength(6) as String
//imageName can save in sqlite to load image later
let fullPath = String("\(docs)/\(imageName).png")
print(fullPath)
let result = imageData.writeToFile(fullPath, atomically: true)
print("FILE WRITTEN SUCCESS=>:\(result)")
}
Load Image from Database
let tempDBObject = self.petListArray[indexPath.row] as! Database
cell?.petName.text = tempDBObject.Hname
//Doc Path
let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first! as String
let imagePath = String("\(documentDirectory)/\(tempDBObject.Hpath!)")
if imagePath == "" {
}else{
cell?.petImageView.image = UIImage(contentsOfFile: imagePath)
}

Resources