如何在Flutter中从SQLite数据库中检索图像数据?

4

我想从SQLite中检索图像数据。 我正在使用以下代码:

var image = await ImagePicker.pickImage(source: imageSource);
List<int> bytes = await image.readAsBytes();

我希望能够从数据库中获取和存储图像,这些图像需要在SQLite数据库中保存。

1
我将图像转换为base64字符串并保存在SQL中,请告诉我是否有更好的解决方案。 - Kenneth Li
你有没有用base64检索图像的有效方法?能否将源代码发送给我? - Shadeeka Nimesh
请等一下,我正在使用手机! - Kenneth Li
3个回答

6

我在我的问题中找到了解决方案。 我正在使用image_picker获取图像,并将其编码为BASE64字符串值,如下所示。

 Uint8List _bytesImage;   
 File _image;
 String  base64Image;

Future getImage() async {
     var image2 = await ImagePicker.pickImage(
      source: ImageSource.gallery,

      );
    List<int> imageBytes = image2.readAsBytesSync();
    print(imageBytes);
    base64Image = base64Encode(imageBytes);
    print('string is');
    print(base64Image);
    print("You selected gallery image : " + image2.path);

    _bytesImage = Base64Decoder().convert(base64Image);

    setState(() {

      _image=image2;

      });
}

在创建 SQLite 数据库后,需要编写 dbhelper.dart 文件以检索字符串值,并编写数据库模型文件 Image.dart 来获取和设置字符串值。

Image.dart

class Image{

  int id;
  String image;


  Employee(this.id, this.image);

   Employee.fromMap(Map map) {
    id= map[id];
    image = map[image];

  }

}

dbhelper.dart

 class DBHelper {
  static Database _db;

  Future<Database> get db async {
    if (_db != null) return _db;
    _db = await initDb();
    return _db;
  }

  initDb() async {
    io.Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, "test.db");
    var theDb = await openDatabase(path, version: 1, onCreate: _onCreate);
    return theDb;
  }

  void _onCreate(Database db, int version) async {
    // When creating the db, create the table
    await db.execute(
        "CREATE TABLE Imagedata(id INTEGER PRIMARY KEY, image TEXT)");
    print("Created tables");
  }

  void saveImage(Imagedata imagedata) async {
    var dbClient = await db;
    await dbClient.transaction((txn) async {
      return await txn.rawInsert(
          'INSERT INTO Imagedata(id, image) VALUES(' +
              '\'' +
              imagedata.id+
              '\'' +
              ',' +
              '\'' +
              imagedata.image +
              '\'' +
              ')');
    });
  }

  Future<List<Imagedata>> getMyImage() async {
    var dbClient = await db;
    List<Map> list = await dbClient.rawQuery('SELECT * FROM Imagedata');
    List<Imagedata> images= new List();
    for (int i = 0; i < list.length; i++) {
      images.add(new Imagedata(list[i]["id"], list[i]["image"]));
    }
    print(images.length);
    return images;
  }

   Future<int> deleteMyImage(Imagedata imagedata) async {
    var dbClient = await db;

    int res =
        await dbClient.rawDelete('DELETE * FROM Imagedata');
    return res;
  }
}

从数据库中获取字符串值并将其解码为图像文件。
从数据库中获取图像。
      Future<List<Employee>> fetchImageFromDatabase() async {
         var dbHelper = DBHelper();
         Future<List<Imagedata>> images= dbHelper.getImages();

                 return images;
            }

将解码后的字符串值转换为图像文件
    String DecoImage;
    Uint8List _bytesImage;

          FutureBuilder<List<Imagedata>>(
          future: fetchImageFromDatabase(),
          builder: (context, snapshot) {

             if (snapshot.hasData) {             
              return new
               ListView.builder(
                  itemCount: snapshot.data.length,
                  itemBuilder: (context, index) {

                      DecoImage=snapshot.data[index].image;
                     _bytesImage = Base64Decoder().convert(DecoImage);

                    return new   SingleChildScrollView(
                      child:  Container(            
                   child: _bytesImage == null 
                      ? new Text('No image value.')
                      :  Image.memory(_bytesImage)
                     ),
                    );
                   }
                 );
                }
              }
           ), 

我认为这对其他Flutter、SQLite开发者有帮助。


0
import 'dart:convert';

import 'dart:typed_data';



    Uint8List bytesImage1;

    bool bolWithImage1 = false;

    try {

      bytesImage1 =

          base64Decode(base64StringFromSql);

      bolWithImage1 = true;

    } catch (err) {}


如果bolWithImage1为真,则转换成功。然后,您可以使用image.memory(byteImage1, ......)在Flutter中显示图像。

0

你也可以将图像保存为BLOB(数据类型:UInt8List)。在sqflite中,将两者都存储为Blob(UInt8List)或String(使用Base64encoder)都可以。关键是要使用MemoryImage而不是Image.memory。否则,您将收到类型“Image”不是类型“ImageProvider”的子类型的错误。

//First create column in database to store as BLOB.
await db.execute('CREATE TABLE $photoTable($colId INTEGER PRIMARY KEY AUTOINCREMENT, $colmage BLOB)');

//User imagePicker to get the image
File imageFile = await ImagePicker.pickImage(source: ImageSource.camera, maxHeight: 200, maxWidth: 200, imageQuality: 70);

//Get the file in UInt8List format
Uint8List imageInBytes = imageFile.readAsBytesSync();

//write the bytes to the database as a blob
db.rawUpdate('UPDATE $photoTable SET $colImage = ?, WHERE $colId =?', [imageInBytes, colID]);

//retrieve from database as a Blob of UInt8List 
var result = await db.query(photoTable, orderBy: '$colID ASC');
List<Photo> photoList = List<Photo>();

for (int i=0; i<result.length; i++){
  photoList.add(Photo.fromMapObject(userMapList[i]));
}

//Map function inside Photo object
Photo.fromMapObject(Map<String, dynamic> map) {
  this._id = map['id'];
  this._imageFile = map['image'];
}


//Display the image using using MemoryImage (returns ImagePicker Object) instead of Image.memory (returns an Image object). 
return Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
     CircleAvatar(
        backgroundImage:  MemoryImage(Photo.image),
        backgroundColor: Colors.blueGrey[50],
      ),
   ]);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接