简体   繁体   English

快速在 Sqlite 中存储和检索图像

[英]Storing and Retrieving Image in Sqlite with swift

How to store and fetch images in SQLite and in what format the images get saved?如何在 SQLite 中存储和获取图像以及图像以什么格式保存? It would be more helpful if explained with an example.如果用一个例子来解释会更有帮助。

Image itself cannot be stored into a database columns but you can first convert it into a string and then store it.图像本身无法存储到数据库列中,但您可以先将其转换为字符串,然后再存储。 The string is called base64 string.该字符串称为 base64 字符串。 As far as I know, any image can be converted to that and reversely.据我所知,任何图像都可以反向转换。

To encode to base 64:要编码为 base 64:

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

Now your UIImage object is converted to a String!现在您的 UIImage 对象被转换为一个字符串! Save strBase64 to SQLite DB.将 strBase64 保存到 SQLite DB。 Remember to use text as column type because this string is very long.请记住使用text作为列类型,因为此字符串很长。

To decode back to UIImage:解码回 UIImage:

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

Alternative替代品

  1. save your image into document directory.将您的图像保存到文档目录中。
  2. save your image file path or name of image in sqlite在sqlite中保存您的图像文件路径或图像名称
  3. Get the image path or name from sqlite and access that path from document directory.从 sqlite 获取图像路径或名称并从文档目录访问该路径。

Take Ref : Iphone : How to Display Document Directory images in Image View?参考 : Iphone : 如何在图像视图中显示文档目录图像?

You can also store your image directly as a BLOB, however it depends on which framework you use for SQLite access.您也可以将图像直接存储为 BLOB,但这取决于您用于 SQLite 访问的框架。 In case you use SQLite.swift , then there is an option:如果您使用SQLite.swift ,则有一个选项:

Set up a file SQLiteHelper.swift like that:像这样设置一个文件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
    }

Now create a file Person.swift and put the following struct inside of it:现在创建一个文件Person.swift并将以下结构放入其中:

import Foundation

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

Store Data存储数据

In order to store data as a .png BLOB you would now basically do something like that:为了将数据存储为 .png BLOB,您现在基本上可以执行以下操作:

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

Retreive Data检索数据

If you want to display the image later in another Imageview you would have to do this:如果您想稍后在另一个 Imageview 中显示图像,则必须执行以下操作:

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

Saving UIImage as BLOB将 UIImage 保存为 BLOB

I have saved the image as a .png because I want to use my database outside of iOS and therefore want to ensure compatibility.我已将图像保存为 .png 格式,因为我想在 iOS 之外使用我的数据库,因此要确保兼容性。 If you want you can also store your UIImage directly.如果你愿意,你也可以直接存储你的UIImage You would roughly need to change it like that:你大概需要像这样改变它:

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
}

Note: SQLite.swift also supports lazy loading, which would probably make more sense in ascenario like that...注意: SQLite.swift还支持延迟加载,这在像这样的场景中可能更有意义......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM