Save Image in Realm

Save image in Realm

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
}

How to put an image in a Realm database?

You can store images as NSData. Given you have the URL of an image, which you want to store locally, here is a code snippet how that can be achieved.

class MyImageBlob {
var data: NSData?
}

// Working Example
let url = NSURL(string: "http://images.apple.com/v/home/cb/images/home_evergreen_hero_iphone_medium.jpg")!
if let imgData = NSData(contentsOfURL: url) {
var myblob = MyImageBlob()
myblob.data = imgData

let realm = try! Realm()
try! realm.write {
realm.add(myblob)
}
}

May be it is a bad idea to do that?

The rule is simple:
If the images are small in size, the number of images is small and they are rarely changed, you can stick with storing them in the database.

If there is a bunch images, you are better off writing them directly to the file system and just storing the path of the image in the database.

Here is how that can be done:

class MyImageStorage{
var imagePath: NSString?
}

let url = NSURL(string: "http://images.apple.com/v/home/cb/images/home_evergreen_hero_iphone_medium.jpg")!
if let imgData = NSData(contentsOfURL: url) {
// Storing image in documents folder (Swift 2.0+)
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
let writePath = documentsPath?.stringByAppendingPathComponent("myimage.jpg")

imgData.writeToFile(writePath, atomically: true)

var mystorage = MyImageStorage()
mystorage.imagePath = writePath

let realm = try! Realm()
try! realm.write {
realm.add(mystorage)
}
}

Please note: Both code samples are not reliable methods for downloading images since there are many pitfalls. In real world apps / in production, I'd suggest to use a library intended for this purpose like AFNetworking or AlamofireImage.



Related Topics



Leave a reply



Submit