【问题标题】:Storing and Retrieving Image in Sqlite with swift使用 swift 在 Sqlite 中存储和检索图像
【发布时间】:2017-06-27 12:59:31
【问题描述】:

如何在 SQLite 中存储和获取图像以及图像以什么格式保存?举例说明会更有帮助。

【问题讨论】:

  • 需要在sqlite中添加图片名称,并将图片保存在文档目录中。
  • 您的图片是本地或服务器 URL,同时您想离线使用该图片,否则
  • 能否请您用swift中的例子详细解释一下

标签: ios swift


【解决方案1】:

图像本身不能存储到数据库列中,但您可以先将其转换为字符串,然后再存储。该字符串称为base64字符串。据我所知,任何图像都可以反向转换。

编码为 base 64:

let image : UIImage = UIImage(named:"imageNameHere")!
let imageData:NSData = UIImagePNGRepresentation(image)!
let strBase64 = imageData.base64EncodedString(options: .lineLength64Characters)

现在您的 UIImage 对象被转换为字符串!将 strBase64 保存到 SQLite DB。记得使用text 作为列类型,因为这个字符串很长。

解码回 UIImage:

let dataDecoded:NSData = NSData(base64EncodedString: strBase64, options: NSDataBase64DecodingOptions(rawValue: 0))!
let decodedimage:UIImage = UIImage(data: dataDecoded)!

【讨论】:

  • 不使用 NSData 直接使用 Swift 3 native Data let decodedData = Data(base64Encoded: base64Str, options: .ignoreUnknownCharacters)
  • 一个更好更好的解释(y)
  • 我正在尝试将 strBase64 保存到带有列类型文本的数据库中,就像你说的那样,但它没有保存。
  • @NishadArora 当你做这样的事情时,很多事情都可能出错。您是否尝试保存一些随机字符串,看看是否会保存?您是否看到任何来自 sql 的错误?也许是sql的问题,而不是base64本身,它只是一个字符串。您是否尝试将字符串保存到位于主包中的 db 文件中?如果是,则需要在进行任何修改之前将其复制到文档文件夹中
  • @Fangming 我尝试保存随机字符串,它被保存在数据库中,在保存基本字符串 64 时也看不到任何错误,也尝试保存数据 blob,现在只剩下一个选项将图像保存在文档目录中,然后将路径保存在本地数据库中。
【解决方案2】:

替代方案

  1. 将图像保存到文档目录中。
  2. 在sqlite中保存你的图片文件路径或图片名称
  3. 从 sqlite 获取图像路径或名称,并从文档目录访问该路径。

请参考:Iphone : How to Display Document Directory images in Image View?

【讨论】:

  • 您确定我们不能将 sqlite 中的图像保存为 NSData 或 blob 或 base 64 字符串吗?
【解决方案3】:

您也可以将图像直接存储为 BLOB,但这取决于您用于 SQLite 访问的框架。如果你使用SQLite.swift,那么有一个选项:

像这样设置一个文件SQLiteHelper.swift

class SQLiteHelper{
    var db: Connection!

    let personsTable = Table("person")
    let id = Expression<Int>("id")
    let firstName = Expression<String>("firstName")
    let lastName = Expression<String>("lastName")
    let profileImage = Expression<Data>("profileImage")
    let date = Expression<Date>("savedAt")

    init() {
        do{
            let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
            let dbTemp = try Connection("\(path)/myDb.sqlite3") //Create db if not existing
            self.db = dbTemp
        }
        catch {
            print("Error info: \(error)")
        }
    }

    public func insertData(firstNameVal: String,
                           lastNameVal: String,
                           profileImageVal: Data,
                           dateVal: Date){

        do{
            //Create a new table only if it does not exist yet
            try db.run(personsTable.create(ifNotExists: true) { t in      // CREATE TABLE "person" (
                t.column(id, primaryKey: true)          //     "id" INTEGER PRIMARY KEY NOT NULL,
                t.column(firstName)                     //     "firstName" TEXT,
                t.column(lastName)                      //     "lastName" TEXT,
                t.column(profileImage)                  //     "profileImage" BLOB,
                t.column(date)                          //     "savedAt" DATETIME)
            })
        }
        catch {
            print("The new SQLite3 Table could not be added: \(error)")
        }

        do{
            try db.run(personsTable.insert(firstName <- firstNameVal,
                                            lastName <- lastNameVal,
                                            profileImage <- profileImageVal,
                                            date <- dateVal
            ))
        }
        catch {
            print("Could not insert row: \(error)")
        }
    }

    public func getData() -> [Person]{
        var persons = [Person]()
        do{
            for row in try db.prepare(personsTable) {
                let person: Person = Person(firstName: row[firstName],
                                               lastName: row[lastName],
                                               profileImage: row[profileImage],
                                               savedAt: row[date])

                persons.append(person)
            }
        }
        catch {
            print("Could not get row: \(error)")
        }
        return persons
    }

现在创建一个文件Person.swift 并将以下结构放入其中:

import Foundation

struct Person: Identifiable {
    var id = UUID()
    var firstName: String
    var lastName: String
    var profileImage: Data
    var savedAt: Date
}

存储数据

为了将数据存储为 .png BLOB,您现在基本上可以执行以下操作:

var databaseHelper: SQLiteHelper = SQLiteHelper.init()
self.databaseHelper.insertData(firstNameVal: "yourFirstName",
                                   lastNameVal: "yourLastName",
                              profileImageVal: yourImageView.pngData(),
                              dateVal: Date())

检索数据

如果您想稍后在另一个 Imageview 中显示图像,您必须这样做:

var persons = self.databaseHelper.getData()
let profileImage = UIImage(data: persons[0].profileImage)
let myImageView = UIImageView(image: profileImage)

将 UIImage 保存为 BLOB

我已将图像保存为 .png,因为我想在 iOS 之外使用我的数据库,因此想确保兼容性。如果您愿意,您也可以直接存储您的 UIImage。你大概需要这样改变它:

let profileImage = Expression<UIImage>("profileImage")
...
profileImageVal: yourImageView,
...
let myImageView = persons[0].profileImage
...

import Foundation
import UIKit

struct Person: Identifiable {
    var id = UUID()
    var firstName: String
    var lastName: String
    var profileImage: UIImage
    var savedAt: Date
}

注意:SQLite.swift 也支持延迟加载,这在这样的场景中可能更有意义...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    • 2017-01-16
    • 2014-04-20
    • 2011-04-30
    • 2015-08-01
    • 2015-03-16
    • 1970-01-01
    相关资源
    最近更新 更多