Flutter - 将网络图像保存到 sqflite

Flutter - Save network image to sqflite

大家好,我想在我的 sqflite 数据库中保护图像我尝试了很多方法,但我只收到无效图像数据或其他错误。

class HomeScreen extends StatelessWidget {

String _base64 ="";

@override
Widget build(BuildContext context) {

() async {
  http.Response response = await http.get(Uri.parse(
      "https://www.mera-petfood.com/files/_processed_/a/4/csm_iStock-521697453_69acb65057.jpg"));

  _base64 = base64Encode(response.bodyBytes);
  
};


Uint8List bytes = base64Decode(_base64);


return Scaffold(
  appBar: null,
  body: SizedBox(
    height: MediaQuery.of(context).size.height,
    width: MediaQuery.of(context).size.width,
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ElevatedButton(
          child: const Text("open database"),
          onPressed: () async {},
        ),

        Image.memory(bytes),
        Text(model.base64String(bytes)),
      ],
    ),
  ),
);
}
}

那是我的实际代码,但我只得到这个异常:

════════ Exception caught by image resource service ════════════════════════════
The following _Exception was thrown resolving an image codec:
Exception: Invalid image data

为什么我解决不了?

有两种方法可以做到这一点。

  1. 将其存储为文件
  2. 将其存储为 blob

对于第二个,您需要先阅读 blob。所以你要这样做的方式是 Make a blob of the image and then save it in the database。现在你可能会问什么是blob?

Blob 代表 binary large object,它是作为单个实体存储的二进制数据的集合。 Blobs 通常是 imagesaudio 或其他 multimedia 对象,但有时二进制可执行代码存储为 blob.

请阅读以下文章:

Saving images: files or blobs?

您的主要问题是没有保存到 sqflite,但您的匿名函数从未被调用。因此,_base64 始终为空字符串。

首先,这行不通:

() async {
  http.Response response = await http.get(Uri.parse(
      "https://www.mera-petfood.com/files/_processed_/a/4/csm_iStock-521697453_69acb65057.jpg"));

  _base64 = base64Encode(response.bodyBytes);
  
};

因为它从未调用过。

应该是(见最后部分():

() async {
  http.Response response = await http.get(Uri.parse(
      "https://www.mera-petfood.com/files/_processed_/a/4/csm_iStock-521697453_69acb65057.jpg"));

  _base64 = base64Encode(response.bodyBytes);
  
}();

其次,不要将匿名函数添加到build,因为它会被重复调用。尝试将其移动为 class 作用域函数。像这样(你需要使用 stateful widget):

class HomeScreen extends StatefulWidget {
    String _base64 ="";
    
    @override
    Widget build(BuildContext context) {
      ...
    }

    void getImage() async {
      http.Response response = await http.get(Uri.parse(
          "https://www.mera-petfood.com/files/_processed_/a/4/csm_iStock-521697453_69acb65057.jpg"));
    
    
       setState(() {
          _base64 = base64Encode(response.bodyBytes);
       });

    };    
}

然后,将其命名为 initState:

@override
void initState() {
   super.initState();
   getImage();
}

最后,在 build 方法中将其用于您的小部件:

@override
Widget build(BuildContext context) {
    return Scaffold(
      appBar: null,
      body: SizedBox(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              child: const Text("open database"),
              onPressed: () async {},
            ),
    
            // When _base64 is empty string, then it means
            // image is on the way. 
            _base64.isEmpty? CircularProgressIndicator(): Image.memory(base64Decode(_base64)),
          ],
        ),
      ),
    );

}