将图像从缓冲区转换为在前端显示(Flutter)

时间:2021-02-19 10:24:06

标签: database mongodb flutter buffer flutter-image

我有一个基于 NodeJS 并使用 mongodb 作为数据库的后端。具有字段名称 photo 的图像保存为对象类型缓冲区。我已使用表单数据从应用程序成功发送图像,但无法在前端显示图像。

这是用于从API获取数据的函数

Future<User> userWithId() async {
  User result;
   try {
      final response = await http.get(
        'api link',
        headers: <String, String>{
          'Authorization': 'Bearer $token',
        },
      );
      if (response.statusCode == 200) {
        result = User.fromJson(jsonDecode(response.body));
      }
   } catch (e) {
      print(e.toString());
   }
  return result;
}

这是 User 类的 fromJson 函数。此处的照片字段将图像作为缓冲区返回。

factory User.fromJson(Map<String, dynamic> json) {
  return User(
    id: json['_id'] as String ?? "",
    email: json['email'] as String ?? "",
    // profilePhoto: json["photo"] ?? null,
    // profilePhoto: base64.encode(jsonDecode(json["photo"])) ?? null,
  );
}

这是照片字段的数据 enter image description here

这是来自MongoDB数据库的数据 enter image description here

6 个答案:

答案 0 :(得分:0)

您可以使用 base64Decode 中的 dart:convert 方法

以字符串格式存储您的图像二进制文件:

factory User.fromJson(Map<String, dynamic> json) {
  return User(
    ...
    profilePhoto: json["photo"] ?? null,
    ...
  );
}

并在用户界面中使用以下代码:

Image.memory(base64Decode(user.profilePhoto))

另外,不要忘记添加一个 if 语句来检查照片是否为空

希望有帮助

答案 1 :(得分:0)

json['photo']['data']['data']; 通过这样做,您会收到此错误 List' is not a subtype of type 'String'。因此,您的 profilePhoto 的返回类型可能是 String。将其更改为动态,然后重试。

答案 2 :(得分:0)

感谢下面解释 dart 中字节的精彩文章,您可以将作为整数列表的响应数据转换为 Uint8List 数据类型并将其传递给 Image.memory< /strong> 渲染图像。

Image.memory(Uint8List.fromList(// pass image data array here));

https://medium.com/flutter-community/working-with-bytes-in-dart-6ece83455721

答案 3 :(得分:0)

试试这个

List<int> imageData = user.profilePhoto['data'] as List<int>
////
Image.memory(Uint8List.fromList(imageData));

答案 4 :(得分:0)

图片类型

你应该修改你的类用户,目前你有:

class User {
  final String id;
  final String email;
  final ? profilePhoto
}

我不确定您当前使用的是哪种类型,但您需要根据您在响应中获得的数据对其进行相应更改。您的图像在您的计算机中是一个字节列表(uint8,表示 8 位的无符号整数,因此为 1 个字节),其值范围为 0 到 255(0 到 0xFF)。


图片标题

您可以阅读 EXIF 以更好地了解标准如何指定图像格式

<块引用>

每个 JPEG 文件都从二进制值 '0xFFD8' 开始,以二进制值 '0xFFD9' 结束。

<块引用>

PNG 文件的前八个字节始终包含以下(十进制)值:137 80 78 71 13 10 26 10


修复

将您的 profilePhoto 的类型更改为 Uint8List,完整代码:

class User {
  final String id;
  final String email;
  String profilePhoto // I don't know which type you use

  User({this.id, this.email, this.profilePhoto});

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      id: json['_id'] as String ?? "",
      email: json['email'] as String ?? "",
      profilePhoto: json["photo"] ?? null,
    );
  }
}

然后使用 Image.memory 将图像加载到您的小部件中,同时要小心,因为它的值可能是 null

return user.profilePhoto != null ? Image.memory(user.profilePhoto) : Container();

注意:Image.memory 是由 MemoryImage 支持的 Image 小部件的简写。

答案 5 :(得分:0)

对于那些也面临这个问题的人来说,这是一个多方面的问题:

  1. 将列表转换为列表。
  2. 使用转换后的列表读取/显示图像。

在 OP 的情况下,获取缓冲区列表将是 profilePhoto: json["photo"]["data"]["data"]

对于第 1 步,将列表转换为列表:

List<dynamic> bufferDynamic = profilePhoto: json["photo"]["data"]["data"];
List<int> bufferInt = buffer.map((e) => e as int).toList();

对于某些人已经提到的第 2 步,请使用 Flutter 提供的 Image.memory class

Image.memory(Uint8List.fromList(bufferInt))

希望这对那些需要从缓冲区读取/显示图像的人有所帮助。 (: