如何在 Flutter 中显示字节数据的图像

dra*_*ook 2 sockets byte image stream flutter

我的项目有两个方面。一个是相机,我们使用 OpenCV 来捕获 8 位 3 通道(R、G、B)的帧,格式化并将其写入套接字以进行流式传输。图像的分辨率为 640 x 480,因此 640x480x3 字节写入套接字。

\n

在另一端,我有一个 Flutter 应用程序正在监听这个套接字。我能够成功收集字节,但无法使用它们重组图像。我怎样才能做到这一点?我正在分享迄今为止所拥有的内容,但无法显示任何视觉效果。

\n
import 'dart:typed_data';\nimport 'package:flutter/material.dart';\nimport 'package:ferenova_flutter_app/plan_display_page/plan_display_page.dart';\nimport 'package:ferenova_flutter_app/vars.dart' as vars;\n\nimport 'dart:io';\n\n// ignore: must_be_immutable\nclass CameraStreamPage extends StatefulWidget {\n  PlanDisplayPageState pdps;\n  Socket socket;\n  String title;\n\n  CameraStreamPage(\n    String title,\n    PlanDisplayPageState pdps,\n  ) {\n    this.title = title;\n    this.pdps = pdps;\n  }\n\n  @override\n  _CameraStreamPage createState() => _CameraStreamPage();\n}\n\nclass _CameraStreamPage extends State<CameraStreamPage> {\n  // VlcPlayerController _vlcViewController;\n  PlanDisplayPageState pdps;\n  Socket socket;\n  Image img;\n  Uint8List bytes;\n\n  @override\n  void initState() {\n    // TODO: implement initState\n    super.initState();\n    pdps = widget.pdps;\n    this.socket = widget.socket;\n\n    img = Image.network(\n        'https://am23.mediaite.com/tms/cnt/uploads/2020/01/babyyoda.jpg');\n    Socket.connect(vars.streamIP, int.parse(vars.streamPORT))\n        .then((Socket sock) {\n      socket = sock;\n      socket.listen(dataHandler,\n          onError: errorHandler, onDone: doneHandler, cancelOnError: false);\n    }).catchError((Object e) {\n      print("Unable to connect: $e");\n    });\n  }\n\n  void dataHandler(data) {\n    String str = new String.fromCharCodes(data).trim();\n    print(str);\n\n    vars.picture += str;\n    int lim = 640 * 480 * 3;\n    if (vars.picture.length >= (640 * 480 * 3)) {\n      bytes = Uint8List.fromList(vars.picture.codeUnits);\n      print('BBBBBBBBBBBBBBBBB: ' + bytes.length.toString());\n      setState(() {\n        img = new Image.memory(\n          bytes,\n          width: 640,\n          height: 480,\n          scale: 1,\n          fit: BoxFit.contain,\n        );\n        vars.picture = vars.picture.substring(lim);\n      });\n    }\n  }\n\n  void errorHandler(error, StackTrace trace) {\n    img = Image.network(\n        'https://am23.mediaite.com/tms/cnt/uploads/2020/01/babyyoda.jpg');\n    print('ERRORORORORORORORROROROR');\n\n    print(error);\n  }\n\n  void doneHandler() {\n    img = Image.network(\n        'https://am23.mediaite.com/tms/cnt/uploads/2020/01/babyyoda.jpg');\n    print('DONEDONEDONEDONEDONEDONE');\n    vars.picture = '';\n    socket.destroy();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Center(\n      // child: SingleChildScrollView(\n      child: Container(\n        width: 1000,\n        height: 600,\n        color: Colors.green[400],\n        child: Column(\n          mainAxisAlignment: MainAxisAlignment.center,\n          // mainAxisSize: MainAxisSize.min,\n          children: <Widget>[\n            Container(\n              width: 900,\n              height: 550,\n              color: Colors.purple,\n              child: img,\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

另外以下是我收到的一部分:

\n
P]rP]rT\\rU^sX^tY_uYcvXbuVcsTaqP^lP^lR_mP^lR_mR_mU^jU^jS]iR\\hQYjS[lR\\oT]pT]pT]pR]mR]mR]mR]mU_pU_pU`nU`nYar[ctZd{]hYiaqhzw\xc2\xa4\xc2\xa1\xc2\xa0\xc2\xa7\xc2\xab\xc2\xa9\xc2\xaa\xc2\xa8\xc2\xa0\xc2\xac\xc2\xa3\xc2\xa0\xc2\xac\xc2\xa3\xc2\xa0\xc2\xaa\xc2\xa2\xc2\xa0\xc2\xaa\xc2\xa2\xc2\xa1\xc2\xa9\xc2\xa1\xc2\xa9\xc2\xa0\xc2\xa8\xc2\xa7\xc2\xa7\xc2\xa7\xc2\xa2\xc2\xa5\xc2\xa2\xc2\xa5\xc2\xa3\xc2\xa3\xc2\xa1\xc2\xa4\xc2\xa1\xc2\xa4\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa0\xc2\xa0\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa2\xc2\xa2\xc2\xa3\xc2\xa2\xc2\xa1\xc2\xa0\xc2\xa0\xc2\xa1\xc2\xa1\xc2\xa1\xc2\xa0\xc2\xa1\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa3\xc2\xa2\xc2\xa3\xc2\xa3\xc2\xa3\xc2\xa3\xc2\xa3\xc2\xa4\xc2\xa4\xc2\xa3\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa4\xc2\xa5\xc2\xa6\xc2\xa6\xc2\xa0\xc2\xa7\xc2\xa0\xc2\xa7\xc2\xa0\xc2\xa7\xc2\xa6\xc2\xa6\xc2\xa0\xc2\xa7\xc2\xa0\xc2\xa7\xc2\xa1\xc2\xa8\xc2\xa2\xc2\xa0\xc2\xa7\xc2\xa1\xc2\xa0\xc2\xa7\xc2\xa1\xc2\xa0\xc2\xa7\xc2\xa1\xc2\xa0\xc2\xa7\xc2\xa1\xc2\xa0\xc2\xa7\xc2\xa1\xc2\xa0\xc2\xa7\xc2\xa1\xc2\xa1\xc2\xa8\xc2\xa2\xc2\xa1\xc2\xa8\xc2\xa2\xc2\xa1\xc2\xa8\xc2\xa2\xc2\xa1\xc2\xa8\xc2\xa2\xc2\xa1\xc2\xa8\xc2\xa2\xc2\xa1\xc2\xa8\xc2\xa2\xc2\xa1\xc2\xa8\xc2\xa2\xc2\xa2\xc2\xa9\xc2\xa3\xc2\xa2\xc2\xa9\xc2\xa3\xc2\xa4\xc2\xaa\xc2\xa4\xc2\xa4\xc2\xaa\xc2\xa4\xc2\xa4\xc2\xaa\xc2\xa4\xc2\xa4\xc2\xaa\xc2\xa4\xc2\xa2\xc2\xa9\xc2\xa3\xc2\xa1\xc2\xa8\xc2\xa2\xc2\xa2\xc2\xa9\xc2\xa3\xc2\xa2\xc2\xa9\xc2\xa3\xc2\xa2\xc2\xa9\xc2\xa3\xc2\xa4\xc2\xaa\xc2\xa4\xc2\xa5\xc2\xab\xc2\xa6\xc2\xa5\xc2\xab\xc2\xa6\xc2\xa4\xc2\xaa\xc2\xa4\xc2\xa4\xc2\xaa\xc2\xa4\xc2\xa4\xc2\xab\xc2\xa3\xc2\xa4\xc2\xab\xc2\xa3\xc2\xa4\xc2\xab\xc2\xa3\xc2\xa4\xc2\xab\xc2\xa3\xc2\xa8\xc2\xaa\xc2\xa3\xc2\xa8\xc2\xaa\xc2\xa3\xc2\xa8\xc2\xaa\xc2\xa3\xc2\xa8\xc2\xaa\xc2\xa3\xc2\xa8\xc2\xa9\xc2\xa4\xc2\xa8\xc2\xa9\xc2\xa4\xc2\xa8\xc2\xa9\n\n\xc2\xa0\xc2\xa1\xc2\xa1\xc2\xa1\xc2\xa0\xc2\xa1\xc2\xa1\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0.'/,$,-&..'/0(33+5MGM`Z_OFE&)!,$!*#$+$%.&)/'*/&,.%+*!'*!',$*+"(*!'*!'("')#()#('!&/).7164.13-0.(+,&),%+)#()"*(!)' ()"**#+.'/3.65085166288286054-31+1.'--&,/&,.%+.%+/&,2)/5,26-38/5:28:28:28=4:=4:<398045-02*.0(+,$(,$(+#'+#'+#'( #'"( #+#'+#')#()#(*$*,%+-)..*/,(-*&+,(-,(-,(--).-(0+&.*%,*%,'"*($+'"*'"**%,+&.+',,(-.'-.'-.'-.'-/).-&,-&,.'-.'-.'-/).-&,,%+,%+.'-.'-/'*+#'*\n
Run Code Online (Sandbox Code Playgroud)\n

dm_*_*_tr 16

你可以试试这个

Image.memory(Uint8List.fromList(YOUR_BYTES));
Run Code Online (Sandbox Code Playgroud)