简体   繁体   English

如何使用 Flutter 将 BASE64 字符串转换为图像?

[英]How to convert BASE64 string into the Image with Flutter?

I extracted a string of BASE64 images from the database, put it on the screen and kept reporting an error我从数据库中提取了一串BASE64图像,放到屏幕上,一直报错

String _base64 = user.data.avatar;
var image = utf8.encode(_base64);
var encoded1 = base64.encode(image);
var bytes = base64.decode(encoded1);

Image.memory(bytes,height: 70),

I'm getting the following error...我收到以下错误...

  Failed decoding image. Data is either invalid, or it is encoded using an unsupported format.
  The following _Exception was thrown resolving an image codec:
  Exception: operation failed

If you know please help me,I'm really worried如果你知道请帮助我,我真的很担心

As previously mentioned in the comments, the cause of this issue is that the base64 String downloaded from the database is being encoded to base64 again.正如前面评论中提到的,这个问题的原因是从数据库下载的base64 String再次被编码为base64。 Since you've mentioned that the image you've fetched from the database is already encoded to base64, there's no need for var image = utf8.encode(_base64);由于您已经提到您从数据库中获取的图像已经编码为 base64,因此不需要var image = utf8.encode(_base64); and var encoded1 = base64.encode(image);var encoded1 = base64.encode(image); in your approach.在你的方法中。

Base64 is a String so no need for utf8.encode() and base64.encode() . Base64 是一个字符串,所以不需要utf8.encode()base64.encode() Your code snippet should look like this.您的代码片段应如下所示。

String _base64 = user.data.avatar;
var bytes = base64.decode(_base64);

Here's a minimal repro to simulate a working sample app that displays image from a base64 String.这是一个模拟工作示例应用程序的最小再现,该应用程序显示来自 base64 字符串的图像。 Clicking the 'Download' button will save the first image displayed from network to the device's internal storage.单击“下载”按钮将从网络显示的第一张图像保存到设备的内部存储器。 The app then converts the downloaded image file to bytes, and then encodes the bytes to base64 - to simulate the base64 String fetched from a database.然后应用程序将下载的图像文件转换为字节,然后将字节编码为 base64 - 以模拟从数据库中获取的 base64 字符串。 The base64 String is then decoded to bytes to be displayed using Image.memory(bytes);然后使用 Image.memory(bytes) 将 base64 字符串解码为要显示的字节;

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

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final imageSrc = 'https://picsum.photos/250?image=9';
  var downloadPath = '';
  var downloadProgress = 0.0;
  Uint8List _imageBytesDecoded;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Expanded(
                flex: 5,
                child: Row(children: [
                  // Display image from network
                  Expanded(
                      flex: 1,
                      child: Column(
                        children: [
                          Text('Image from Network'),
                          Image.network(imageSrc),
                        ],
                      )),
                  Expanded(
                    flex: 1,
                    child: Container(
                      child: Column(
                        children: [
                          Text('Image from File storage'),
                          downloadPath == ''
                              // Display a different image while downloadPath is empty
                              // downloadPath will contain an image file path on successful image download
                              ? Icon(Icons.image)
                              : Image.file(File(downloadPath)),
                        ],
                      ),
                    ),
                  ),
                ])),
            Expanded(
              flex: 1,
              child: Row(
                children: [
                  ElevatedButton(
                    // Download displayed image from imageSrc
                    onPressed: () {
                      downloadFile().catchError((onError) {
                        debugPrint('Error downloading: $onError');
                      }).then((imagePath) {
                        debugPrint('Download successful, path: $imagePath');
                        displayDownloadImage(imagePath);
                        // convert downloaded image file to memory and then base64
                        // to simulate the base64 downloaded from the database
                        base64encode(imagePath);
                      });
                    },
                    child: Text('Download'),
                  ),
                  ElevatedButton(
                    // Delete downloaded image
                    onPressed: () {
                      deleteFile().catchError((onError) {
                        debugPrint('Error deleting: $onError');
                      }).then((value) {
                        debugPrint('Delete successful');
                      });
                    },
                    child: Text('Clear'),
                  )
                ],
              ),
            ),
            LinearProgressIndicator(
              value: downloadProgress,
            ),
            Expanded(
                flex: 5,
                child: Column(
                  children: [
                    Text('Image from base64'),
                    Center(
                      child: _imageBytesDecoded != null
                          ? Image.memory(_imageBytesDecoded)
                          // Display a temporary image while _imageBytesDecoded is null
                          : Icon(Icons.image),
                    ),
                  ],
                )),
          ],
        ),
      ),
    );
  }

  displayDownloadImage(String path) {
    setState(() {
      downloadPath = path;
    });
  }

  // Convert downloaded image file to memory and then base64
  // to simulate the base64 downloaded from the database
  base64encode(String imagePath) async {
    var imageBytes = File(imagePath).readAsBytesSync();
    debugPrint('imageBytes: $imageBytes');
    // This simulates the base64 downloaded from the database
    var encodedImage = base64.encode(imageBytes);
    debugPrint('base64: $encodedImage');
    setState(() {
      _imageBytesDecoded = base64.decode(encodedImage);
      debugPrint('imageBytes: $_imageBytesDecoded');
    });
  }

  Future deleteFile() async {
    final dir = await getApplicationDocumentsDirectory();
    var file = File('${dir.path}/image.jpg');
    await file.delete();
    setState(() {
      // Clear downloadPath and _imageBytesDecoded on file deletion
      downloadPath = '';
      _imageBytesDecoded = null;
    });
  }

  Future downloadFile() async {
    Dio dio = Dio();
    var dir = await getApplicationDocumentsDirectory();
    var imageDownloadPath = '${dir.path}/image.jpg';
    await dio.download(imageSrc, imageDownloadPath,
        onReceiveProgress: (received, total) {
      var progress = (received / total) * 100;
      debugPrint('Rec: $received , Total: $total, $progress%');
      setState(() {
        downloadProgress = received.toDouble() / total.toDouble();
      });
    });
    // downloadFile function returns path where image has been downloaded
    return imageDownloadPath;
  }
}

演示

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

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