【发布时间】:2017-06-27 12:59:31
【问题描述】:
如何在 SQLite 中存储和获取图像以及图像以什么格式保存?举例说明会更有帮助。
【问题讨论】:
-
需要在sqlite中添加图片名称,并将图片保存在文档目录中。
-
您的图片是本地或服务器 URL,同时您想离线使用该图片,否则
-
能否请您用swift中的例子详细解释一下
如何在 SQLite 中存储和获取图像以及图像以什么格式保存?举例说明会更有帮助。
【问题讨论】:
图像本身不能存储到数据库列中,但您可以先将其转换为字符串,然后再存储。该字符串称为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)!
【讨论】:
let decodedData = Data(base64Encoded: base64Str, options: .ignoreUnknownCharacters)
替代方案
请参考:Iphone : How to Display Document Directory images in Image View?
【讨论】:
您也可以将图像直接存储为 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)
我已将图像保存为 .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 也支持延迟加载,这在这样的场景中可能更有意义...
【讨论】: