I'm trying to provide a user selection of an image from Photo Library. Thus I'm using UIImagePickerController for selecting. But here comes an issue with getting its initial URL in the file system (I need this for CKAsset).
My code.
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
let imageURL = info[UIImagePickerControllerReferenceURL] as NSURL
let path = imageURL.path!
let imageName = path.lastPathComponent
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentDirectory = paths.first as String!
let localPath = documentDirectory + "/" + imageName
let imageData = NSData(contentsOfFile: localPath)!
let image = UIImage(data: imageData)!
picker.dismissViewControllerAnimated(true, completion: nil)
}
imageURL is kinda cryptic. It describes Asset URL, but not one in File System. And it looks like: assets-library://asset/asset.JPG?id=B6C0A21C-07C3-493D-8B44-3BA4C9981C25&ext=JPG.
According to this logic the path is /asset.JPG where asset.JPG is a name of the image.
Then I'm accessing my Documents folder and trying to find there a file with path:
/Users/Eugene/Library/Developer/CoreSimulator/Devices/3C5E9A23-8220-4B37-BD14-F1E42EEC2C7C/data/Containers/Data/Application/20EBAAE2-6C6F-4651-A48F-16A222CCB3A2/Documents/asset.JPG
Cryptic as well but seems to be a real path for a not existing image... No image with that path can be found. And this makes me sick.
Do I have to save an image from the beginning? Or is there any other way to go?
I've looked through several tutorials using AssetsLibrary API but I didn't find anything useful to solve my problem. Thank you in advance!
Okay, I've solved the issue.
All you have to do is simply grab the image (info[UIImagePickerControllerOriginalImage] as UIImage) and save to the given directory. If you need to save only 1 picture it works great. The code id below.
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
let imageURL = info[UIImagePickerControllerReferenceURL] as NSURL
let imageName = imageURL.path!.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as String
let localPath = documentDirectory.stringByAppendingPathComponent(imageName)
let image = info[UIImagePickerControllerOriginalImage] as UIImage
let data = UIImagePNGRepresentation(image)
data.writeToFile(localPath, atomically: true)
let imageData = NSData(contentsOfFile: localPath)!
let photoURL = NSURL(fileURLWithPath: localPath)
let imageWithData = UIImage(data: imageData)!
picker.dismissViewControllerAnimated(true, completion: nil)
}
In SWIFT 4 u Can Try This, It's working properly.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let imgUrl = info[UIImagePickerControllerImageURL] as? URL{
let imgName = imgUrl.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
let localPath = documentDirectory?.appending(imgName)
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
let data = UIImagePNGRepresentation(image)! as NSData
data.write(toFile: localPath!, atomically: true)
//let imageData = NSData(contentsOfFile: localPath!)!
let photoURL = URL.init(fileURLWithPath: localPath!)//NSURL(fileURLWithPath: localPath!)
print(photoURL)
}
APPDEL.window?.rootViewController?.dismiss(animated: true, completion: nil)
}
For Swift 5+ ;according to #Jaydip answer
if let imgUrl = info[UIImagePickerController.InfoKey.imageURL] as? URL{
let imgName = imgUrl.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
let localPath = documentDirectory?.appending(imgName)
let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
let data = image.pngData()! as NSData
data.write(toFile: localPath!, atomically: true)
//let imageData = NSData(contentsOfFile: localPath!)!
let photoURL = URL.init(fileURLWithPath: localPath!)//NSURL(fileURLWithPath: localPath!)
print(photoURL)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
//this block of code grabs the path of the file
let imageURL = info[UIImagePickerControllerReferenceURL] as NSURL
let imagePath = imageURL.path!
let localPath = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(imagePath)
//this block of code adds data to the above path
let path = localPath.relativePath!
let imageName = info[UIImagePickerControllerOriginalImage] as UIImage
let data = UIImagePNGRepresentation(imageName)
data?.writeToFile(imagePath, atomically: true)
//this block grabs the NSURL so you can use it in CKASSET
let photoURL = NSURL(fileURLWithPath: path)
}
check this solution.
import AssetsLibrary
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
self.imagePicker = picker
if let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
let controller = CropViewController(image: selectedImage )
controller.delegate = self
picker.presentViewController(controller, animated: true, completion: nil)
}
else if let imageUrl = info[UIImagePickerControllerReferenceURL] as? NSURL{
let assetLibrary = ALAssetsLibrary()
assetLibrary.assetForURL(imageUrl , resultBlock: { (asset: ALAsset!) -> Void in
if let actualAsset = asset as ALAsset? {
let assetRep: ALAssetRepresentation = actualAsset.defaultRepresentation()
let iref = assetRep.fullResolutionImage().takeUnretainedValue()
let image = UIImage(CGImage: iref)
let controller = CropViewController(image: image)
controller.delegate = self
picker.presentViewController(controller, animated: true, completion: nil)
}
}, failureBlock: { (error) -> Void in
})
}
}
In swift 4
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let imgUrl = info[UIImagePickerControllerReferenceURL] as? URL{
let imgName = imgUrl.lastPathComponent
let documentDirectory = NSTemporaryDirectory()
let localPath = documentDirectory.appending(imgName)
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
let data = UIImageJPEGRepresentation(image, 0.3)! as NSData
data.write(toFile: localPath, atomically: true)
let photoURL = URL.init(fileURLWithPath: localPath)
}
}
swift 4.2
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
//obtaining saving path
let fileManager = FileManager.default
let documentsPath = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first
let imagePath = documentsPath?.appendingPathComponent("image.jpg")
// extract image from the picker and save it
if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
let imageData = pickedImage.jpegData(compressionQuality: 0.75)
try! imageData?.write(to: imagePath!)
}
}
Thanks
let imgUrl = info[UIImagePickerController.InfoKey.imageURL] as? URL
Related
I going to fetch directory of photo From UIImagepicker using delegates method. but how to do this i don't know so give me hint for this isssue
This line you can get the path of your photo in swift 3++:
let imageUrl = info[UIImagePickerControllerReferenceURL] as? NSURL
You can use it in delegate function func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
Code:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
// get image url
let imageUrl = info[UIImagePickerControllerReferenceURL] as? NSURL
let imageName = imageUrl?.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageName!)
if !FileManager.default.fileExists(atPath: localPath!.path) {
do {
try UIImageJPEGRepresentation(image, 1.0)?.write(to: localPath!)
print("file saved")
}catch {
print("error saving file")
}
}
else {
print("file already exists")
}
}
Note:- This question is only for Swift 3.0
I am able to get the path prio to Swift 3.0
I want to get UIImage's path picked in didFinishPickingMediaWithInfo method
let imageUrl = info[UIImagePickerControllerReferenceURL] as? NSURL
let imageName = imageUrl.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageName!)
But this path is not pointing to my image, Even there is no any image in Documents folder.
Can anyone help me on this?
You can't access the path of the picked image directly. You need to save that in your DocumentsDirectory and then take the image back with the path.
Do this
Swift 3.x
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
let imageUrl = info[UIImagePickerControllerReferenceURL] as? NSURL
let imageName = imageUrl?.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageName!)
if !FileManager.default.fileExists(atPath: localPath!.path) {
do {
try UIImageJPEGRepresentation(image, 1.0)?.write(to: localPath!)
print("file saved")
}catch {
print("error saving file")
}
}
else {
print("file already exists")
}
}
Also note that you are using the name as the last path component which is same for every file. So, this will save your image in DocumentDirectory only once as it will find the path next time.
Now when you access the localPath variable and navigate to the path, you will find the image.
NOTE:
If you are using a device here, then you need to download the container of the device, show its package contents and navigate to the Documents Directory where you will find your saved image.
In SWIFT 4 U Can Try This, It's working properly.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let imgUrl = info[UIImagePickerControllerImageURL] as? URL{
let imgName = imgUrl.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
let localPath = documentDirectory?.appending(imgName)
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
let data = UIImagePNGRepresentation(image)! as NSData
data.write(toFile: localPath!, atomically: true)
//let imageData = NSData(contentsOfFile: localPath!)!
let photoURL = URL.init(fileURLWithPath: localPath!)//NSURL(fileURLWithPath: localPath!)
print(photoURL)
}
APPDEL.window?.rootViewController?.dismiss(animated: true, completion: nil)
}
Handle selected image or video:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
print("ok")
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
//what to do to save that image
} else {
//how to get the video and save
}
}
Save it to the document directory:
let path = try! NSFileManager.defaultManager().URLForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomain: NSSearchPathDomainMask.UserDomainMask, appropriateForURL: nil, create: false)
let newPath = path.URLByAppendingPathComponent("image.jpg") //or video.mpg for example
How to save that image to following newPath?
Use following steps to save Image to documents directory
Step 1: Get a path to document directory
let path = try! NSFileManager.defaultManager().URLForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomain: NSSearchPathDomainMask.UserDomainMask, appropriateForURL: nil, create: false)
Step 2: Append FileName in path
let newPath = path.stringByAppendingPathComponent("image.jpg")
Step 3: Decide filetype of Image either JPEG or PNG and convert image to data(byte)
//let pngImageData = UIImagePNGRepresentation(image) // if you want to save as PNG
let jpgImageData = UIImageJPEGRepresentation(image, 1.0) // if you want to save as JPEG
Step 4: write file to created path
let result = jpgImageData!.writeToFile(newPath, atomically: true)
Add above code into your didFinishPickingImage function.
Use following func to save video to documents directory
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject])
{
// *** store the video URL returned by UIImagePickerController *** //
let videoURL = info[UIImagePickerControllerMediaURL] as! NSURL
// *** load video data from URL *** //
let videoData = NSData(contentsOfURL: videoURL)
// *** Get documents directory path *** //
let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0]
// *** Append video file name *** //
let dataPath = documentsDirectory.stringByAppendingPathComponent("/videoFileName.mp4")
// *** Write video file data to path *** //
videoData?.writeToFile(dataPath, atomically: false)
}
Updating the accepted answer to Swift 3 in Xcode 8.3.3
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
let path = try! FileManager.default.url(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask, appropriateFor: nil, create: false)
let newPath = path.appendingPathComponent("image.jpg")
let jpgImageData = UIImageJPEGRepresentation(image, 1.0)
do {
try jpgImageData!.write(to: newPath)
} catch {
print(error)
}
} else {
let videoURL = info[UIImagePickerControllerMediaURL] as! NSURL
let videoData = NSData(contentsOf: videoURL as URL)
let path = try! FileManager.default.url(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask, appropriateFor: nil, create: false)
let newPath = path.appendingPathComponent("/videoFileName.mp4")
do {
try videoData?.write(to: newPath)
} catch {
print(error)
}
}
}
Swift 5
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true)
guard let image = info[.editedImage] as? UIImage else {
print("No image found")
return
}
// saving to application directory
let imageName = UUID().uuidString
let imagePath = getDocumentsDirectory().appendingPathComponent(imageName)
if let jpegData = image.jpegData(compressionQuality: 0.8) {
print("Image Save to path \(imagePath)")
try? jpegData.write(to: imagePath)
}
}
I'm trying to get the URL of an image imported from Library in Swift to send it to Apple Watch with transferFile(_:metadata) but I'm having two error on NSURL.
This is my code:
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!)
{
imagePicked.image = image
let imageUrl = editingInfo[UIImagePickerControllerReferenceURL] as! NSURL
let imageName = imageUrl.path!.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as String!
let localPath = documentDirectory.stringByAppendingPathComponent(imageName)
let image = editingInfo[UIImagePickerControllerOriginalImage]as! UIImage
let data = UIImagePNGRepresentation(image)
data!.writeToFile(localPath, atomically: true)
let photoURL = NSURL(fileURLWithPath: localPath)
self.dismissViewControllerAnimated(true, completion: nil);
}
And I'm getting error with *imageName and *localPath because it says that:
'lastPathComponent' is unavailable: Use lastPathComponent on NSURL instead.
'stringByAppendingPathComponent' is unavailable: Use URLByAppendingPathComponent on NSURL instead.
But I can't get it right in Swift 2.0 and Xcode 7. Where am I going wrong?
Apple has changed something in their NSString and NSURL library in their latest release (iOS 9), but those methods are available from iOS 4. You can check the related Apple Forum Post for more details.
For fixing this error, you need to change the code like:
Swift 2:
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!)
{
let imageUrl = editingInfo[UIImagePickerControllerReferenceURL] as! NSURL
let imageName = imageUrl.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as String!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.URLByAppendingPathComponent(imageName!)
let image = editingInfo[UIImagePickerControllerOriginalImage]as! UIImage
let data = UIImagePNGRepresentation(image)
data!.writeToFile(localPath.absoluteString, atomically: true)
self.dismissViewControllerAnimated(true, completion: nil);
}
Swift 3:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
let imageUrl = info[UIImagePickerControllerReferenceURL] as! NSURL
let imageName = imageUrl.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageName!)
let image = info[UIImagePickerControllerOriginalImage]as! UIImage
let data = UIImagePNGRepresentation(image)
do
{
try data?.write(to: localPath!, options: Data.WritingOptions.atomic)
}
catch
{
// Catch exception here and act accordingly
}
self.dismiss(animated: true, completion: nil);
}
Reference:
lastPathComponent
URLByAppendingPathComponent:
As of iOS 11, you can get the image URL from the info dictionary with the key UIImagePickerControllerImageURL.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let imageURL = info[UIImagePickerControllerImageURL] as? URL
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
//this block of code grabs the path of the file
let imageURL = info[UIImagePickerControllerReferenceURL] as NSURL
let imagePath = imageURL.path!
let localPath = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(imagePath)
//this block of code adds data to the above path
let path = localPath.relativePath!
let imageName = info[UIImagePickerControllerOriginalImage] as UIImage
let data = UIImagePNGRepresentation(imageName)
data?.writeToFile(imagePath, atomically: true)
//this block grabs the NSURL so you can use it in CKASSET
let photoURL = NSURL(fileURLWithPath: path)
}
I have this code and I'm having a problem trying to get the image path :(
I searched in google and stack over flow but the solution that I found were in objective-c or code that doesn't work anymore in swift :(
so this is my code :
#IBAction func chooseWaterMark(sender: AnyObject) {
var photoPicker = UIImagePickerController()
photoPicker.delegate = self
photoPicker.sourceType = .PhotoLibrary
presentViewController(photoPicker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
waterMark.image = image
waterMarkAlpha.image = image
waterMarkAlpha.alpha = CGFloat(0.5)
dismissViewControllerAnimated(false, completion: nil)
}
This code may help you:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
let imageURL = info[UIImagePickerControllerReferenceURL] as NSURL
let imageName = imageURL.path!.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as String
let localPath = documentDirectory.stringByAppendingPathComponent(imageName)
let image = info[UIImagePickerControllerOriginalImage] as UIImage
let data = UIImagePNGRepresentation(image)
data.writeToFile(localPath, atomically: true)
let imageData = NSData(contentsOfFile: localPath)!
let photoURL = NSURL(fileURLWithPath: localPath)
let imageWithData = UIImage(data: imageData)!
picker.dismissViewControllerAnimated(true, completion: nil)
}
With this code you can save image to the given directory. Hope it will help.