Flutter中展示Base64图片

在flutter中难免会用到Base64照片,通过dart:convert库我们可以很容易加载Base64图片。

Flutter中如何展示Base64照片

在flutter中的Base64Decoder().convert方法的的参数是base64图片中,后面的部分。所以我们需要进行截取,实现的主要代码如下:

import 'dart:convert';

const String base64Str = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgAgMAAAAOFJJnAAAADFBMVEUAAAAWFyMYGCMXHCilIQtpAAAABHRSTlMAmV8tOa34CwAAAEdJREFUGNNjoAdgPgDBDLwJDAycBSBGBAODKojBFMbAMLUByACSQDYIqCZwRoAZnBGqQPVgRSAlYEVAJRBFEVAGZwLCEhoAAKvbDA7roJ+AAAAAAElFTkSuQmCC';

Image.memory(
  Base64Decoder().convert(base64Str.split(',')[1]),
  width: 22.0,
  height: 22.0,
)

如果用上面的方法,发现在ListView中使用,滚动ListView的时候会出现重复渲染,并且渲染很慢。框架没有比较base64字符串,所以一张已经存在的照片被当作一张新的照片来处理。下面介绍如何避免多次解码重渲染问题

Base64图片多次解码重渲染问题

我们可以用StatefulWidget,在initState方法中的数据进行解码,从而避免多次对图像进行解码,提升性能和改善用户体验。
下面是封装的Base64Image Widget:

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

import 'package:flutter/material.dart';

/// 加载Base64资源,避免避免多次解码图像
class Base64Image extends StatefulWidget {

  /// base资源,已处理的
  final String source;

  /// 未处理的base64资源
  final String base64;

  /// 图像宽度
  final double width;

  /// 图像高度
  final double height;

  /// 缩放比例
  final double scale;

  Base64Image({
    Key key,
    this.source,
    this.base64,
    this.height: 22.0,
    this.width: 22.0,
    this.scale: 1.0,
  }) : super(key: key);

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

class _Base64ImageState extends State<Base64Image> {
  Uint8List _source;

  @override
  void initState() {
    _source = Base64Decoder().convert(widget.source ?? widget.base64.split(',')[1]);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Image.memory(
      _source,
      height: widget.height,
      width: widget.width,
      scale: widget.scale,
    );

  }
}

背景图中使用Base64图片

我们可以在Container中设置Base64图片为背景图:

Container(
  decoration: BoxDecoration(
    image: DecorationImage(
      image: MemoryImage(
        Base64Decoder().convert(base64Str.split(',')[1]),
        scale: widget.scale ?? 1
      )
    )
  )
)