【问题标题】:Save image in Realm在 Realm 中保存图像
【发布时间】:2016-10-20 11:04:32
【问题描述】:

我正在尝试从设备的照片库中选择图片的方法:

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

并将这张图片保存在 Realm 中(作为 NSData):

asset.assetImage = UIImagePNGRepresentation(userPhoto.image!)! as NSData?

...

   try! myRealm.write
        {
            user.assetsList.append(asset)
            myRealm.add(user)
        }

构建成功并尝试选择并保存图像(在应用程序中)后,我遇到应用程序错误: '二进制太大'

我做错了什么?

附:对不起我的英语:)


经过一些操作后,我得到了这段代码。但它会覆盖我的图像。

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

【问题讨论】:

  • 调试并打印你的 imageName let imageName = imageUrl.lastPathComponent 如果它总是同名,则图像被覆盖。图像名称必须是唯一的。类似于 let timestampFilename = String(Int(Date().timeIntervalSince1970)) + "_newImage.png"
  • 效果很好!非常感谢!

标签: swift realm


【解决方案1】:

不要将图像本身保存到领域,只需将图像的位置作为字符串或 NSString 保存到领域,然后从该保存的路径加载图像。性能方面,从该物理位置加载图像总是更好,并且您的数据库不会变得太大

  func loadImageFromPath(_ path: NSString) -> UIImage? {

        let image = UIImage(contentsOfFile: path as String)

        if image == nil {
            return UIImage()
        } else{
            return image
        }
    }

或者你只是保存图像名称,如果它在你的文档目录中的话

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    
    }

这里是一个粗略的示例,如何使用唯一名称将捕获的图像保存到您的目录:

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

【讨论】:

  • 谢谢回答!保存捕获图像 - 这意味着我已将图像从 PhotoLibrary 复制到我的应用程序的图像目录?你能告诉我如何在 didFinishPickingMediaWithInfo 方法中获取捕获图像的路径(NSURL)吗?
  • 1.当我试图保存图片时,它正在重写。
  • 2.当我重新启动我的应用程序(在模拟器中) - 我没有图像(以前)
  • 重写是什么意思?覆盖?当您使用模拟器时,检查每个图像的图像名称是否唯一,图像仅存在于该特定模拟器实例中。如果你重置模拟器,图像就消失了。这很正常。在我们的手机上,它们将留在您的应用目录中
【解决方案2】:

https://realm.io/docs/objc/latest/#current-limitations 最大数据大小为 16 MB。这是领域的限制

【讨论】:

    【解决方案3】:

    根据您序列化图像数据的方式(例如,如果它是无损位图),该数据很可能超过 16MB,正如您所说,这是 Realm 支持的二进制属性的最大大小。

    当你调用 NSData.length 时,它说你的数据有多大?

    【讨论】:

    • 您必须压缩图像,因为单个 NSData 属性不能超过 16MB
    • 如果您对我的回答感到满意,请给它一个正确的标记或将其作为答案,以便它可以帮助其他人。 :)
    • 如何压缩我的 NSData?或者也许我必须存储文件的路径 - 我怎样才能获得文件的路径?
    猜你喜欢
    • 1970-01-01
    • 2016-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多