如何在 Flutter 中显示从 .NET Core API 加载的 jpeg 图像?

Posted

技术标签:

【中文标题】如何在 Flutter 中显示从 .NET Core API 加载的 jpeg 图像?【英文标题】:How to display jpeg image loaded from .NET Core API in Flutter? 【发布时间】:2020-07-02 15:45:12 【问题描述】:

我正在尝试显示从 .NET Core Web API 加载的 jpeg 图像。但是,似乎我在编码方面做错了。有时我没有错误,但图像不可见且不显示。有时我会收到以下错误:

Could not instantiate image codec.

我尝试了几种方法来显示图像,但都没有成功。

包含 jpeg 图像的 Web API 响应:

显示图片的应用页面截图:

从 API 加载图像的代码:

Future<Uint8List> _loadFileBytes(String fileId) async 
    var bytesResponse = await fileHttpService.getFileBytes(fileId);
    if (bytesResponse.statusCode != 200) _handlePhotoLoadError();
    var bytesStr = bytesResponse.body;
    var bytes = utf8.encode(bytesStr);
    return bytes;
  

在 photo 属性中接收 jpeg 图像字节的 Widget 代码试图显示它:

import 'package:flutter/material.dart';
import 'package:.../models/PhotoModel.dart';
import 'package:image/image.dart' as imageUtils;

class PhotoView extends StatefulWidget 
  final PhotoModel photo;

  PhotoView(@required this.photo);

  @override
  PhotoViewState createState() => PhotoViewState();


class PhotoViewState extends State<PhotoView> 
  double displayHeight;
  double displayWidth;

  @override
  void initState() 
    displayHeight = 1;
    displayWidth = 1;
    super.initState();
  

  @override
  Widget build(BuildContext context) 
    displayHeight = MediaQuery.of(context).size.height;
    displayWidth = MediaQuery.of(context).size.width;
    return Container(
        child: Stack(
      children: <Widget>[
        Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Flexible(
                  flex: 18,
                  child: Container(
                    decoration: BoxDecoration(
                        borderRadius: BorderRadius.all(
                            Radius.circular(displayWidth * 0.1)),
                        boxShadow: [
                          BoxShadow(
                              blurRadius: displayWidth * 0.05,
                              color: Color.fromRGBO(0, 0, 0, 0.5),
                              offset: Offset(
                                  displayWidth * 0.01, displayWidth * 0.025))
                        ]),
                    child: ClipRRect(
                        borderRadius: BorderRadius.all(
                            Radius.circular(displayWidth * 0.015)),
                        child: _futureBuildImage()),
                  )),
            ]),
      ],
    ));
  

  void deleteButtonPressed() 
    showMessageDialog("", "Säker på att du vill radera fotot?");
    print("Delete button pressed!!!");
  

  void showMessageDialog(String title, String body) 
    try 
      showDialog(
          context: context,
          builder: (BuildContext context) 
            return AlertDialog(
              title: new Text(body),
              content: Row(
                mainAxisSize: MainAxisSize.max,
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Expanded(
                    child: FlatButton(
                      onPressed: deleteDialogYesPressed,
                      child: Text("Radera"),
                    ),
                  ),
                  Expanded(
                      child: FlatButton(
                    onPressed: deleteDialogNoPressed,
                    child: Text("Avbryt"),
                  ))
                ],
              ),
            );
          );
     catch (e) 
      print(e.toString());
    
  

  void deleteDialogYesPressed() 
    Navigator.pop(context);
  

  void deleteDialogNoPressed() 
    Navigator.pop(context);
  

  Widget _futureBuildImage() 
    var futureBuilder = FutureBuilder<Widget>(
      future: _decodeImage(),
      initialData: Container(),
      builder: _createImage,
    );
    return futureBuilder;
  

  Future<Widget> _decodeImage() async 
    try 
      var byteData =
          await (await decodeImageFromList(widget.photo.bytes)).toByteData();
      var bytes = byteData.buffer.asUint8List();
      var image = Image.memory(bytes);

      return image;
     catch (e) 
      return Container();
    
  

  Widget _createImage(BuildContext context, AsyncSnapshot<Widget> snapshot) 
    if (snapshot.connectionState == ConnectionState.none ||
        snapshot.connectionState == ConnectionState.active ||
        snapshot.connectionState == ConnectionState.waiting)
      return Container();
    else if (snapshot.connectionState == ConnectionState.done)
      return snapshot.data;
    else
      return Container();
  


如果您想知道为什么我使用 utf8 对字节字符串进行编码,这只是我尝试过的另一种方法。我不知道应该怎么做才能显示在 Web API 响应中收到的图像。

这让我发疯了。 感谢您的帮助!

【问题讨论】:

什么是getFileBytes 【参考方案1】:

在尝试了不同的方法后,我终于找到了一个非常简单的解决方案。我不明白为什么我没有从一开始就以这种方式工作。这很简单。 以下是可能遇到相同问题的其他人的步骤:

第一步,通过Response.bodyBytes属性获取字节:

Future<Uint8List> _loadFileBytes(String fileId) async 
    var bytesResponse = await fileHttpService.getFileBytes(fileId);
    if (bytesResponse.statusCode != 200) _handlePhotoLoadError();
    var bytes = bytesResponse.bodyBytes;
    return bytes;
  

第 2 步,只需将 int 数组传递给 Image.memory() 方法即可。

child: Image.memory(widget.photo.bytes)

我现在觉得自己像个白痴。希望这可以帮助其他人至少面临同样的问题。得了。

【讨论】:

以上是关于如何在 Flutter 中显示从 .NET Core API 加载的 jpeg 图像?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Asp.net 核心向 Flutter 应用发送推送通知

如何从存储中选择多个图像并在 Flutter 和 Flutter Web App 中显示? [关闭]

Flutter - 如何从 Firestore 中检索 ID 列表并在 GridView 中显示它们的项目?

Flutter 在使用 StreamBuilder 从 firebase 加载数据之前显示红色错误屏幕,如何解决?

如何创建一个 Flutter Futurebuilder 函数来显示从 JSON 中获取的字符串数组?

Flutter - 如何在“Future”中显示“snackbar”