Search code examples
fluttersqflite

Flutter - Save network image to sqflite


Hello guys i want to safe an image in my sqflite database i tried many thing but i only get errors like invalid image data or something else.

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)),
      ],
    ),
  ),
);
}
}

thats my actual code but i only get this Exception:

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

Why is it not working i cant solve it?


Solution

  • Your main problem is not saving to sqflite, but your anonymous function is never called. So, the _base64 is always empty string.

    First, this not works:

    () 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);
      
    };
    

    because it never called.

    It should be (see the last part with ():

    () 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);
      
    }();
    

    Second, you should not add the anonymous function to build because it will be called repeatedly. Try moving it as class scope function. Something like this (You need to use 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);
           });
    
        };    
    }
    

    then, called it initState:

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

    and, finally, use it to your widget in build method:

    @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)),
              ],
            ),
          ),
        );
    
    }