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

Posted

技术标签:

【中文标题】将图像从缓冲区转换为前端显示(颤振)【英文标题】:Convert Image from Buffer to display in Frontend (Flutter) 【发布时间】:2021-05-22 08:07:25 【问题描述】:

我有一个基于 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 函数。这里的 photo 字段将图像作为缓冲区返回。

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

这是来自照片字段的数据

这是来自 MongoDB 数据库的数据

【问题讨论】:

@android_id 如何从 json 中获取 img 字符串? 你能分享你的json吗 @Android_id 我无法打印 json,因为它太大了。您可以从 mongo db 指南针查看图像。 json['photo']['data']['data'] 返回整数列表 ```` type 'List' 不是类型 'String' 的子类型 ```` 出现此错误 @Android_id 它是一个数组 【参考方案1】:

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

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

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

并在 UI 中使用以下代码:

Image.memory(base64Decode(user.profilePhoto))

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

希望对你有帮助

【讨论】:

type '_InternalLinkedHashMap&lt;String, dynamic&gt;' is not a subtype of type 'String' 使用json["photo"] 时出现此错误@ 使用json["photo"]['data']['data'] 时出现此错误type 'List&lt;dynamic&gt;' is not a subtype of type 'String'【参考方案2】:

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

【讨论】:

能提供相关代码吗?【参考方案3】:

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

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

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

【讨论】:

我正在考虑获取整数列表的问题【参考方案4】:

这样试试

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

【讨论】:

我试过了,但是 ══╡ 图像资源服务发现异常╞═════════════════════════════ ════════════════════════ 解析图像编解码器时引发了以下_Exception:异常:无效的图像数据引发异常时,这是堆栈: #0 _futurize (dart:ui/painting.dart:5275:5) #1 ImageDescriptor.encoded (dart:ui/painting.dart:5143:12) #2 instantiateImageCodec (dart:ui/painting.dart:1999:60) 【参考方案5】:

图片类型

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

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 小部件的简写。

【讨论】:

【参考方案6】:

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

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

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

对于第 1 步,将 List 转换为 List:

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))

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

【讨论】:

以上是关于将图像从缓冲区转换为前端显示(颤振)的主要内容,如果未能解决你的问题,请参考以下文章

如何将 rgb 图像数组从 sws_scale 转换为 DIB(在内存位图中)

Yii2 在后端从前端显示图像 - 设置别名

将图像从 firebase 显示到颤振应用程序 [关闭]

如何使用 React 前端从 Mongoose 显示带有 <img> 的图像

前端监控和页面卡顿

如何使用颤振将时间戳从 Firebase 转换为 DateTime