Flutter Exception: Invalid image data

Viewed 3105

I am working on a Flutter application that uploads to and gets data from PostgreSQL Database. I am using postgres: ^2.3.2 in pubspec.yaml file.

First, I am converting the image to base64. And then, I am uploading the image to the database as BYTEA.

And when I query the image data from the database, it provides me with an integer list. I searched the web, and found that I had to convert that list to Uint8List. After converting it to Uint8List, I have to use the Image.memory method to convert the Uint8List to an image widget. But when I do so, I get this error on the Debug Console:

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

When the exception was thrown, this was the stack
#0      _futurize (dart:ui/painting.dart:5326:5)
#1      ImageDescriptor.encoded (dart:ui/painting.dart:5194:12)
#2      instantiateImageCodec (dart:ui/painting.dart:2048:60)
<asynchronous suspension>
════════════════════════════════════════════════════════════════════════════════

And this image on the device: Device screenshot

The code is below:

import 'dart:typed_data';
import 'package:flutter/material.dart';

class ShowImage extends StatefulWidget {
  const ShowImage({Key? key}) : super(key: key);

  @override
  _ShowImageState createState() => _ShowImageState();
}

class _ShowImageState extends State<ShowImage> {
  dynamic _image;
  Map data = {};

  void setImage() async {
    GetImage getImgObj = GetImage(connection: data['connection']);

    dynamic imgBytes = await getImgObj.getImage();

    print(imgBytes.runtimeType);

    setState(() {
      _image = Image.memory(imgBytes);
    });
  }

  @override
  Widget build(BuildContext context) {
    data = ModalRoute.of(context)!.settings.arguments as Map;

    // setImage();

    return Scaffold(
      appBar: AppBar(
        title: Text("Show Image"),
        centerTitle: true,
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(18.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              ElevatedButton(
                onPressed: () {
                  setImage();
                },
                child: Text("Get Image"),
              ),
              SizedBox(height: 10.0),
              Container(
                width: 100,
                height: 350,
                decoration:
                    BoxDecoration(border: Border.all(color: Colors.grey)),
                child: _image == null
                    ? Align(
                        alignment: Alignment.center,
                        child: Text(
                          "Image not selected",
                          textAlign: TextAlign.center,
                        ),
                      )
                    : Align(
                        alignment: Alignment.center,
                        child: _image,
                      ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class GetImage {
  var connection;

  GetImage({this.connection});

  Future<dynamic> getImage() async {
    int itemId = 1;
    String query = "SELECT img FROM lawbreach WHERE lid = $itemId;";

    List<dynamic> results = await this.connection.query(query);

    final bytes = Uint8List.fromList(results[0][0]);

    return bytes;
  }
}

I tried searching every corner of the web, but couldn't find any solution. Hope, someone here has an answer to my question :)

2 Answers

The reason why the Image widget throws an "Invalid image data" Exception is because the base64 that you're trying to load is invalid. You need to check if the encoded base64 image that you've downloaded is being encoded to base64 again. Decode the downloaded base64 encoded image before loading it to the widget.

Uint8List _imageBytesDecoded = base64.decode(encodedImage);

...

Image.memory(_imageBytesDecoded)

How I solved my own, I extracted the image because it was in zip folder and go to pubspect.yaml assets: - images/image_22.jpg then in my widget I then added child: Image.asset('images/image_22.jpg')

Related