How To Add A Image In CoreData And How to Save The Image In CoreData [duplicate] - swift

This question already has answers here:
Saving Picked Image to CoreData
(2 answers)
Closed 4 years ago.
How to add an image in core data? The image type what that I have selected. And how to save the core data image. How can I add a image?

Step 1:- Save the image in Document Directory
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") //Possibly you Can pass the dynamic name here
// Save this name in core Data using you code as a String.
let jpgImageData = UIImageJPEGRepresentation(image, 1.0)
do {
try jpgImageData!.write(to: newPath)
} catch {
print(error)
}
}}
Step:-2: Fetch the Image back from the Document Directory and display index path row wise in table view cell.
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("image.png") //Pass the image name fetched from core data here
let image = UIImage(contentsOfFile: imageURL.path)
cell.imageView.image = image
}
This is simple and More convenient Method

Related

loadImageFromDisk - function modyfication swift

im using the below code to load a downloaded image from disk, when the file exists I can load it as image. If it doesn't image returns as nil.
How could I modify the code to replace return nil with loading a placeholder image from my asset folder called default.png. So instead of returning nil, there is always an image return, either downloaded one that's trying to load or if it doesn't exist, my own asset image.
func loadImageFromDiskWith(fileName: String) -> UIImage? {
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(fileName)
let image = UIImage(contentsOfFile: imageUrl.path)
return image
}
return nil
}
You can do as below -
func loadImageFromDiskWith(fileName: String) -> UIImage {
let documentDirectory = FileManager.SearchPathDirectory.documentDirectory
let userDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(documentDirectory, userDomainMask, true)
var image = UIImage(named: "default") // Make sure there must be "default.png" in your main bundle.
if let dirPath = paths.first {
let imageUrl = URL(fileURLWithPath: dirPath).appendingPathComponent(fileName)
if FileManager.default.fileExists(atPath: imageUrl.path) { //Check here for file existence. It won't crash.
image = UIImage(contentsOfFile: imageUrl.path)
}
}
return image
}

How to save selected image from photo gallery to show any view controller in swift

I'm working on my app and i got stuck at one point.
There is one UIIMAGEVIEW and one UPLOAD button.
So when user click UPLOAD button he get to photo gallery to select image after selecting image I'm showing that image on UIIMAGEVIEW.
So my question is:-
after showing image on UIIMAGEVIEW i want to save that image on app to show that same image on different View Controller.
In this case you can try this code snippet:
func saveImgToDocumentDirectory(image: UIImage ) {
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let fileName = "image.png" // image name for identify particular image
let fileURL = documentsDirectory.appendingPathComponent(fileName)
if let data = UIImageJPEGRepresentation(image, 1.0),!FileManager.default.fileExists(atPath: fileURL.path){
do {
try data.write(to: fileURL)
print("file saved")
} catch {
print("error saving file:", error)
}
}
}
func loadImgFromDocumentDirectory(nameOfImage : String) -> UIImage {
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(nameOfImage)
let image = UIImage(contentsOfFile: imageURL.path)
return image!
}
return UIImage.init(named: "default.png")!
}
Image name is a unique identifier for the image, while storing you are required to specify the image name "imageName", so it would be easy to fetch that particular image using the same name.
You can put the image in a global variable. A global variable can be used through all the app. :
var imageSelected:UIImage? // Value will be nil if no image has been set
class ViewController1 {
// Puts your image inside a global variable
image = yourImage
}
class ViewController2 {
// Uses the image that was defined inside the global variable
#IBOutlet weak var imageView: UIView!
imageView.image = imageSelected
}

swift image picker gets several pictures

i have a problem with inserting images into a CollectionView cell using an ImagePicker. The problem is, if I click on a photo which I would like to insert quickly several times, then the photo is inserted several times in different cells.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
picker.dismiss(animated: true, completion: nil)
picker.allowsEditing = true
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
collectionViewController?.imageArray.append(pickedImage)
collectionViewController?.newImages.append(pickedImage)
let guid = UUID()
let fileManager = FileManager.default
let imagePath = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("\(guid).png")
let data = UIImagePNGRepresentation(fixOrientation(img: pickedImage))
fileManager.createFile(atPath: imagePath as String, contents: data, attributes: nil)
let image = CoreDataManager.shared.createImageyObject(pfad: imagePath, date: Date(), guid: guid)
collectionViewController?.images.append(image)
if collectionViewController?.images.count == 1 {
collectionViewController?.images[0].isBaseImage = true
collectionViewController?.lastIndex = 0
}
collectionViewController?.update()
}
}
Mediainfo contains image url, media url... Maybe you should cache picked imageURL (that unique) in a Set then check if imageURL that's already existed.

Save UIImage array to disk

I have a UIImage array that I'm trying to save to disk (documents directory). I've converted it to Data so it can be saved but I can't figure out the correct/best way to save that [Data] to disk.
(arrayData as NSArray).write(to: filename, atomically: false) doesn't seem right or there seems like there is some better way.
Code so far:
// Get the new UIImage
let image4 = chartView.snapShot()
// Make UIImage into Data to save
let data = UIImagePNGRepresentation(image4!)
// Add Data image to Data Array
arrayData.append(data!)
// Get Disk/Folder
let filename = getDocumentsDirectory().appendingPathComponent("images")
// This is how I'd Write Data image to Disk
// try? data?.write(to: filename)
// TODO: Write array Data images to Disk
(arrayData as NSArray).write(to: filename, atomically: false)
To save your images to the document directory, you could start by creating a function to save your image as follows. The function handles creating the image name for you and returns it.
func saveImage(image: UIImage) -> String {
let imageData = NSData(data: UIImagePNGRepresentation(image)!)
let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
let docs = paths[0] as NSString
let uuid = NSUUID().uuidString + ".png"
let fullPath = docs.appendingPathComponent(uuid)
_ = imageData.write(toFile: fullPath, atomically: true)
return uuid
}
Now since you want to save an array of images, you can simply loop and call the saveImage function:
for image in images {
saveImage(image: image)
}
If you prefer to name those images yourself, you can amend the first function to the following:
func saveImage(image: UIImage, withName name: String) {
let imageData = NSData(data: UIImagePNGRepresentation(image)!)
let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
let docs = paths[0] as NSString
let name = name
let fullPath = docs.appendingPathComponent(name)
_ = imageData.write(toFile: fullPath, atomically: true)
}
When you save an image as a UIImagePNGRepresentation as you are trying to do, please note that is does not save orientation for you. This means that when you attempt to retrieve the image, it might be titled to the left. You will need to redraw your image to make sure it has the right orientation as this post will explain how to save png correctly. However, if you save your image with UIImageJPEGRepresentation you will not have to worry about all that and you can simply save your image without any extra effort.
EDITED TO GIVE ARRAY OF IMAGES
To retrieve the images you have saved, you can use the following function where you pass an array of the image names and you get an array back:
func getImage(imageNames: [String]) -> [UIImage] {
var savedImages: [UIImage] = [UIImage]()
for imageName in imageNames {
if let imagePath = getFilePath(fileName: imageName) {
savedImage.append(UIImage(contentsOfFile: imagePath))
}
}
return savedImages
}
Which relies on this function to work:
func getFilePath(fileName: String) -> String? {
let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
var filePath: String?
let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
if paths.count > 0 {
let dirPath = paths[0] as NSString
filePath = dirPath.appendingPathComponent(fileName)
}
else {
filePath = nil
}
return filePath
}
You can below code to stored image into local.
let fileManager = NSFileManager.defaultManager()
let paths = (NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString).stringByAppendingPathComponent("ImageName.png")
let image = YOUR_IMAGE_TO_STORE.
let imageData = UIImageJPEGRepresentation(image!, 0.5)
fileManager.createFileAtPath(paths as String, contents: imageData, attributes: nil)

Save image in Realm

I'm trying to pick image from device's Photo Library in method:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
userPhoto.image = info[UIImagePickerControllerOriginalImage] as! UIImage?
userPhoto.contentMode = .scaleAspectFill
userPhoto.clipsToBounds = true
dismiss(animated: true, completion: nil)
}
and save this picture in Realm (as NSData):
asset.assetImage = UIImagePNGRepresentation(userPhoto.image!)! as NSData?
...
try! myRealm.write
{
user.assetsList.append(asset)
myRealm.add(user)
}
After build succeeded and trying to pick and save image (in the app) i have app error:
'Binary too big'
What i'm doing wrong?
P.S. Sorry for my English :)
After some actions i have this code. But it's overwrite my image.
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
}
userPhoto.image = image
userPhoto.contentMode = .scaleAspectFill
userPhoto.clipsToBounds = true
urlCatch = (localPath?.path)!
self.dismiss(animated: true, completion: nil);
}
Don't save the image itself into realm, just save the location of the image into realm as String or NSString and load the image from that saved path. Performance wise it's always better to load images from that physical location and your database doesn't get too big
func loadImageFromPath(_ path: NSString) -> UIImage? {
let image = UIImage(contentsOfFile: path as String)
if image == nil {
return UIImage()
} else{
return image
}
}
or you just save the image name, if it's in your documents directory anyhow
func loadImageFromName(_ imgName: String) -> UIImage? {
guard imgName.characters.count > 0 else {
print("ERROR: No image name")
return UIImage()
}
let imgPath = Utils.getDocumentsDirectory().appendingPathComponent(imgName)
let image = ImageUtils.loadImageFromPath(imgPath as NSString)
return image
}
and here a rough example how to save a captured image to your directory with a unique name:
#IBAction func capture(_ sender: AnyObject) {
let videoConnection = stillImageOutput?.connection(withMediaType: AVMediaTypeVideo)
stillImageOutput?.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (imageDataSampleBuffer, error) -> Void in
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
//self.stillImage = UIImage(data: imageData!)
//self.savedImage.image = self.stillImage
let timestampFilename = String(Int(Date().timeIntervalSince1970)) + "someName.png"
let filenamePath = URL(fileReferenceLiteralResourceName: getDocumentsDirectory().appendingPathComponent(timestampFilename))
let imgData = try! imageData?.write(to: filenamePath, options: [])
})
/* helper get Document Directory */
class func getDocumentsDirectory() -> NSString {
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = paths[0]
//print("Path: \(documentsDirectory)")
return documentsDirectory as NSString
}
https://realm.io/docs/objc/latest/#current-limitations
maximum data size is 16 MB . this is limitation of realm
Depending on how your serializing the image data (for example if it's a lossless bitmap), it's quite possible that this data exceed 16MB, which as you've stated is Realm's maximum supported size for binary properties.
When you invoke NSData.length, how large does it say your data is?