You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Image.memory加载Uint8List Buffer图片失败问题求助

问题:Flutter中Buffer数组转Image.memory报错“Invalid image data”

收到的后端Buffer数据格式

{
  "type": "Buffer",
  "data": [
    239,
    191,
    189,
    80,
    78,
    71,
    13,
    10,
    26,
    ...
  ]
}

定义的响应DTO(Freezed)

@freezed
class FileDownloadResponse with _$FileDownloadResponse {
  factory FileDownloadResponse({
    /// 文件类型
    @JsonKey(name: 'type') required String type,

    /// 缓冲区数据
    @JsonKey(name: 'data') required List<int> imageBuffer,
  }) = _FileDownloadResponse;

  factory FileDownloadResponse.fromJson(Map<String, dynamic> json) => _$FileDownloadResponseFromJson(json);
}

构建Image.memory的代码

class SelectProfileWidget extends StatelessWidget {
  final List<int>? imageBuffer;
  final double? height;
  final double? width;
  final double? iconHeight;
  final double? iconWidth;

  SelectProfileWidget({
    Key? key,
    this.imageBuffer,
    this.height,
    this.width,
    this.iconHeight,
    this.iconWidth,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    if (imageBuffer != null) {
      return Image.memory(
        Uint8List.fromList(imageBuffer!),
        height: height ?? 88,
        width: width ?? 88,
        fit: BoxFit.cover,
      );
    }
    return const SizedBox.shrink();
  }
}

运行时错误日志

E/FlutterJNI( 3742): Failed to decode image
E/FlutterJNI( 3742): android.graphics.ImageDecoder$DecodeException: Failed to create image decoder with message 'unimplemented'Input contained an error.
E/FlutterJNI( 3742):    at android.graphics.ImageDecoder.nCreate(Native Method)
E/FlutterJNI( 3742):    at android.graphics.ImageDecoder.access$200(ImageDecoder.java:173)
E/FlutterJNI( 3742):    at android.graphics.ImageDecoder$ByteBufferSource.createImageDecoder(ImageDecoder.java:250)
E/FlutterJNI( 3742):    at android.graphics.ImageDecoder.decodeBitmapImpl(ImageDecoder.java:1847)
E/FlutterJNI( 3742):    at android.graphics.ImageDecoder.decodeBitmap(ImageDecoder.java:1840)
E/FlutterJNI( 3742):    at io.flutter.embedding.engine.FlutterJNI.decodeImage(FlutterJNI.java:524)

======== Exception caught by image resource service ================================================
The following _Exception was thrown resolving an image codec:
Exception: Invalid image data

When the exception was thrown, this was the stack: 
#0      _futurize (dart:ui/painting.dart:5718:5)
#1      ImageDescriptor.encoded (dart:ui/painting.dart:5574:12)
#2      instantiateImageCodec (dart:ui/painting.dart:2056:60)
<asynchronous suspension>
====================================================================================================

问题

代码存在什么问题?有没有其他将Buffer数组转换为图片组件的方法?


问题分析与解决方法

1. 核心问题:Buffer数据开头存在无效字节

从给出的data数组开头可以看到前三个字节是239, 191, 189,这是UTF-8的替换字符(�),属于无效的图片文件头。正常PNG的文件头应该是89, 50, 4E, 47(对应十六进制89PNG),而你的数据开头多了这三个无效字节,导致图片解码器无法识别格式。

2. 解决步骤

方案一:修复后端数据(优先)

联系后端开发人员,确认返回的Buffer开头为何带有这三个无效字节,让后端返回纯净的图片二进制数据,不要附加额外字符。

方案二:前端手动过滤无效字节(临时 workaround)

如果后端暂时无法修改,可以在前端处理时去掉开头的三个无效字节,同时添加错误处理避免崩溃:

@override
Widget build(BuildContext context) {
  if (imageBuffer != null && imageBuffer!.length > 3) {
    // 移除前三个无效字节
    final validBuffer = imageBuffer!.sublist(3);
    return Image.memory(
      Uint8List.fromList(validBuffer),
      height: height ?? 88,
      width: width ?? 88,
      fit: BoxFit.cover,
      errorBuilder: (context, error, stackTrace) {
        // 解码失败时显示占位图标
        return const Icon(Icons.broken_image, size: 44);
      },
    );
  }
  return const SizedBox.shrink();
}

3. 额外验证方法

可以将imageBuffer保存为本地文件,用图片查看器打开,或者用十六进制编辑器查看文件头,确认是否符合对应图片格式的标准头(比如PNG标准头为89 50 4E 47 0D 0A 1A 0A),这样能快速定位数据是否损坏。


内容的提问来源于stack exchange,提问作者Jun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 14:55:23