简体   繁体   English

如何在 flutter 中显示来自 api 响应的 png 图像?

[英]How to display a png image from api response in flutter?

I'm getting a PNG image (NOT URI) as a response to my api request as shown bellow:我收到一个 PNG 图像(不是 URI)作为对我的 api 请求的响应,如下所示:

Future PostToGetPostImages(String pic_id,String pic_type) async {
    try {
      var parms = {
        'code': pic_type+"_"+pic_id,
      };

      Response response = await _dio.post(_get_post_image,
          data: parms,
          options: Options(contentType: Headers.formUrlEncodedContentType),
          onSendProgress: (int sent, int total) {
            print('sent : $sent // total : $total');
          }, onReceiveProgress: (v, s) {
            print('v : $v // s : $s');
          });

      print('***** Response body Download Profile Images: ${response.data} **********');
      
      return response.data;
    } catch (error, stacktrace) {
      _handleError(error);
      print("Exception occured A: $error stackTrace: $stacktrace");
    }
  }

This is what it print after execution:这是执行后打印的内容:

I/flutter (12777): ***** Response body Download Profile Images: �PNG

I need to know how to display this response ( the png image ) in flutter, I'm using this code but it's not working:我需要知道如何在 flutter 中显示此响应(png 图像),我正在使用此代码,但它不起作用:

FutureBuilder(
                    future: aptProvider().PostToGetProfileImages("1", "m"),
                    builder: (context, snapshot) {
                      return CircleAvatar(
                          radius: 65.0,
                          backgroundImage: backgroundImage: NetworkImage(snapshot.data
                            .toString()));
                    }),

也许 png 就像一个像 404 这样的虚拟图像,就像附加图像中的图像一样,所以你必须复制并尝试使用 Image.network 检查它,如果一切正常,你继续使用 image.network

If you are getting the image url from the response, then you can use the Image.network(imageUrl)如果您从响应中获取图像 url,则可以使用Image.network(imageUrl)

OR或者

If you are getting the imageData in the form of Uint8List, then you can use the Image.memory(imageData)如果您以 Uint8List 的形式获取 imageData,那么您可以使用Image.memory(imageData)

The problem here that you is not using a URL image, confirm to use a URL end with (.png, jpg, ..etc.) and also confirm it by open it in your browser.这里的问题是您没有使用 URL 图像,请确认使用以(.png、jpg、.. 等)结尾的 URL,并通过在浏览器中打开它来确认。

then然后

to display it in you widget use one of this ways要在您的小部件中显示它,请使用以下方式之一

First第一的

Image.network('URL') 
// ex: Image.network('https://picsum.photos/250?image=9')

Second第二

Container( height : 100 , width :100 , decoration : Box decoration ( 
  image : Decoration image ( Network image ('URL'), ), 
), ), ),

It seems like you get the image as a byte array, base64 string.看起来您将图像作为字节数组,base64 字符串。

Here is how I solve that.这是我解决这个问题的方法。

var base64 = response.split(';base64,')[1];
base64 = base64.replaceFirst('binary data/', '');
Uint8List bytes = base64Decode(base64);

// Image Widget which you can put in anywhere.
Image.memory(bytes, fit: BoxFit.contain)

I'm not sure if you got it to work but I wanted to leave this for future reference:我不确定你是否让它工作,但我想留下这个以供将来参考:

You are receiving raw bytes as part of the response;您正在接收原始字节作为响应的一部分; from there you will need to use those to create an image.从那里您将需要使用它们来创建图像。 For this you have two options:为此,您有两种选择:

  1. Save the bytes to a file.将字节保存到文件中。
  2. Show the image bytes straight from memory.直接显示来自 memory 的图像字节。

Option 1 is usually what you want, but if you need a quick test you can do option 2 without issues, keep in mind memory is limited.选项 1 通常是您想要的,但如果您需要快速测试,您可以毫无问题地执行选项 2,请记住 memory 是有限的。 Both have different implementations depending on the packages you are using.两者都有不同的实现,具体取决于您使用的包。

Here's a quick overview of what Option 2 might look like using just plain old http :以下是仅使用普通的旧http选项 2 的简要概述:

// MyRepository.dart
class Repository {
  Future<Uint8List?> getImageBytes(<...some params>) async {
    final streamResponse = await client.send(<...some req>);
    final response = await Response.fromStream(streamResponse);
    if (response.statusCode == 200) {
      parsedResponse = response.bodyBytes;
    }
    return null;
  }
}

// MyWidget.dart
class MyWidget extends StatelessWidget {

  <... some other code>

  final Uint8List imageRawBytes;

  @override
  Widget build(BuildContext context) {
    return Image.memory(
      imageRawBytes,
    );
  }
}

What's important here is that you use the raw response bytes instead of using a response body (which is usually an encoded String).这里重要的是您使用原始响应字节而不是使用响应主体(通常是编码的字符串)。 This way you can build either a File or keep them in memory to be used.这样,您可以构建File或将它们保存在 memory 中以供使用。

Please share a example of your json data after that I can help you more over you used a incorrect format of function.请分享您的json数据示例,然后我可以帮助您更多地使用不正确的函数格式。 You need to use mvvm technique你需要使用 mvvm 技术

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM