将图像从缓冲区转换为前端显示(颤振)
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你可以使用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<String, dynamic>' is not a subtype of type 'String'
使用json["photo"]
时出现此错误@ 使用json["photo"]['data']['data']
时出现此错误type 'List<dynamic>' 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(在内存位图中)