【问题标题】:How to convert BASE64 string into Image with Flutter?如何使用 Flutter 将 BASE64 字符串转换为 Image?
【发布时间】:2018-02-19 02:11:55
【问题描述】:

我正在将我的 Firebase 数据库中保存的图像转换为 Base64,并希望进行解码和编码。我研究了类似的问题,但仍然遇到错误。这是我目前所拥有的?

var image1 = String;

var pic = event.snapshot.value['image'];
var photo = BASE64.decode(pic);
image1 = photo;

我收到以下错误...

A value of type "List<int>" cannot be assigned to a variable of type "Type"

如果您可以提供将图像编码为 Base64 的反向过程,以便可以将它们保存回 Firebase,我们将不胜感激。

***更新

这是我更新的代码,但仍然抛出错误。

image1 = event.snapshot.value['image'];
var image = BASE64.decode(image1.toString());
new Image.memory(image),

错误是……

FormatException: Invalid Length must be a multiple of 4

【问题讨论】:

    标签: image list base64 converter flutter


    【解决方案1】:

    使用'dart:convert' 包有一个更简单的方法

    Image.memory(base64Decode(base64String));
    

    实现和一些有用的方法:

    import 'dart:convert';
    import 'dart:typed_data';
    import 'package:flutter/widgets.dart';
    
    
    Image imageFromBase64String(String base64String) {
      return Image.memory(base64Decode(base64String));
    }
    
    Uint8List dataFromBase64String(String base64String) {
      return base64Decode(base64String);
    }
    
    String base64String(Uint8List data) {
      return base64Encode(data);
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用 Image.memory 构造函数将 Uint8List 转换为 Flutter Image 小部件。 (如有必要,使用Uint8List.fromList 构造函数将List 转换为Uint8List。)您可以使用BASE64.encode 进行其他操作。

      这里有一些示例代码。

      import 'dart:async';
      import 'dart:convert';
      import 'dart:typed_data';
      import 'package:flutter/material.dart';
      import 'package:http/http.dart' as http;
      
      void main() {
        runApp(new MyApp());
      }
      
      class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return new MaterialApp(
            theme: new ThemeData.dark(),
            home: new MyHomePage(),
          );
        }
      }
      
      class MyHomePage extends StatefulWidget {
        @override
        State createState() => new MyHomePageState();
      }
      
      class MyHomePageState extends State<MyHomePage> {
        String _base64;
      
        @override
        void initState() {
          super.initState();
          (() async {
            http.Response response = await http.get(
              'https://flutter.io/images/flutter-mark-square-100.png',
            );
            if (mounted) {
              setState(() {
                _base64 = BASE64.encode(response.bodyBytes);
              });
            }
          })();
        }
      
        @override
        Widget build(BuildContext context) {
          if (_base64 == null)
            return new Container();
          Uint8List bytes = BASE64.decode(_base64);
          return new Scaffold(
            appBar: new AppBar(title: new Text('Example App')),
            body: new ListTile(
              leading: new Image.memory(bytes),
              title: new Text(_base64),
            ),
          );
        }
      }
      

      但是,在数据库中存储大量二进制数据通常不是一个好主意。它没有发挥 Firebase 实时数据库的优势,您最终会浪费带宽传输您不需要的数据以及不必要的编码和解码。您应该改用firebase_storage 插件,将图片的路径或下载 URL 存储在数据库中。

      【讨论】:

      • 知道了。现在它说Uint8ClampedList cannot be assigned to variable Uint8List?请解释
      • 当我运行这个new Image.memory(photo.toList()),我的应用程序中断并且我收到以下错误Format Exception: Invalid Length, must be multiple of 4请帮助
      • 请用您正在使用的代码更新您的问题,因为我没有看到对toList() 的调用。听起来你直接在String 上调用toList(),这将产生一个base64 字符的List。此列表不是解码图像的二进制表示,因此这可能就是您在无法渲染时遇到错误的原因。使用new Uint8List.fromList()将解码后的图像(decode()的输出)转换为Uint8List。
      • 也就是说,我强烈建议您尝试使用 firebase_storage,它比将 base64 编码图像存储在数据库中要好得多。
      • 谢谢@CollinJackson,问题是我目前有一个iOS Swift 应用程序,我正在更新我用Base64 保存用户照片的地方。只有少数用户,但我想允许他们访问他们的照片,如果他们更改了照片,则将它们和新的照片保存到 FirebaseStorage。我已经用我的新结果更新了问题。
      【解决方案3】:
      Uint8List _bytesImage;
      
      String _imgString = 'iVBORw0KGgoAAAANSUhEUg.....';
      
      _bytesImage = Base64Decoder().convert(_imgString);
      
      Image.memory(_bytesImage)
      

      【讨论】:

      • 如何在 CircleAvatar 背景图像上使用它?我尝试了几件事,包括backgroundImage: Image.memory(_bytesImage);
      • 没关系,我发现我可以在末尾添加.image 并且它有效:backgroundImage: Image.memory(_bytesImage).image;
      【解决方案4】:

      打开相机照片(临时文件夹),编辑文件,然后将其转换为 Base64:

      代码:

      import 'dart:convert';
      import 'package:image/image.dart' as ImageProcess;
      
      File file = File(imagePath);
      final _imageFile = ImageProcess.decodeImage(
        file.readAsBytesSync(),
      );
      
      ...edit file...
      
      String base64Image = base64Encode(ImageProcess.encodePng(_imageFile));
      

      解码并显示:

      import 'dart:convert';
      import 'package:image/image.dart' as ImageProcess;
      
      final _byteImage = Base64Decoder().convert(base64Image);
      Widget image = Image.memory(_byteImage)
      

      【讨论】:

        【解决方案5】:

        通过这个简单的方法,我可以设置一个抖动的图像。 image 属性是base64图像作为字符串,例如:

        TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb2
        

        尝试下一个:

        Widget getImagenBase64(String imagen) {
            _imageBase64 = imagen;
            const Base64Codec base64 = Base64Codec();
            if (_imageBase64 == null) return new Container();
            bytes = base64.decode(_imageBase64);
            return Image.memory(
                  bytes,
                  width: 200,
                  fit: BoxFit.fitWidth,
               
            );
          }
        

        我希望这对你有用。编码愉快。

        【讨论】:

          【解决方案6】:

          导入

          import 'dart:convert';
          import 'dart:typed_data';
          

          从屏幕加载数据并分配给这个变量

              Uint8List _bytes;
            _bytes = Base64Decoder().convert("iVBORw0KGgoAAAANSUhEUgAAANgAAA......");
          

          在代码树结构小部件中

          Image.memory(_bytes)
          

          【讨论】:

            猜你喜欢
            • 2019-09-22
            • 2017-12-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-04-10
            • 1970-01-01
            • 1970-01-01
            • 2015-12-20
            相关资源
            最近更新 更多