【Flutter】三、Flutter之图片

夏景胜
2023-12-01

FLutter中可使用Image获取来自网络、文件、内容、asset的图片。

1.Image构造器

一、构造函数
const Image({
    Key key,
    @required this.image,
    this.frameBuilder,
    this.loadingBuilder,
    this.semanticLabel,
    this.excludeFromSemantics = false,
    this.width,
    this.height,
    this.color,
    this.colorBlendMode,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.centerSlice,
    this.matchTextDirection = false,
    this.gaplessPlayback = false,
    this.filterQuality = FilterQuality.low,
  }) : assert(image != null),
       assert(alignment != null),
       assert(repeat != null),
       assert(filterQuality != null),
       assert(matchTextDirection != null),
       super(key: key);

二、命名构造函数
// 2.1 用于创建来自网络的图片
Image.network(
    String src, {
    Key key,
    double scale = 1.0,
    this.frameBuilder,
    this.loadingBuilder,
    this.semanticLabel,
    this.excludeFromSemantics = false,
    this.width,
    this.height,
    this.color,
    this.colorBlendMode,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.centerSlice,
    this.matchTextDirection = false,
    this.gaplessPlayback = false,
    this.filterQuality = FilterQuality.low,
    Map<String, String> headers,
  }) : image = NetworkImage(src, scale: scale, headers: headers),
       assert(alignment != null),
       assert(repeat != null),
       assert(matchTextDirection != null),
       super(key: key);
// 2.2 创建来自文件为图片
Image.file(
    File file, {
    Key key,
    double scale = 1.0,
    this.frameBuilder,
    this.semanticLabel,
    this.excludeFromSemantics = false,
    this.width,
    this.height,
    this.color,
    this.colorBlendMode,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.centerSlice,
    this.matchTextDirection = false,
    this.gaplessPlayback = false,
    this.filterQuality = FilterQuality.low,
  }) : image = FileImage(file, scale: scale),
       loadingBuilder = null,
       assert(alignment != null),
       assert(repeat != null),
       assert(filterQuality != null),
       assert(matchTextDirection != null),
       super(key: key);
// 2.3 创建来自asset的图片
Image.asset(
    String name, {
    Key key,
    AssetBundle bundle,
    this.frameBuilder,
    this.semanticLabel,
    this.excludeFromSemantics = false,
    double scale,
    this.width,
    this.height,
    this.color,
    this.colorBlendMode,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.centerSlice,
    this.matchTextDirection = false,
    this.gaplessPlayback = false,
    String package,
    this.filterQuality = FilterQuality.low,
  }) : image = scale != null
         ? ExactAssetImage(name, bundle: bundle, scale: scale, package: package)
         : AssetImage(name, bundle: bundle, package: package),
       loadingBuilder = null,
       assert(alignment != null),
       assert(repeat != null),
       assert(matchTextDirection != null),
       super(key: key);
// 2.4 创建来自内存的图片
Image.memory(
    Uint8List bytes, {
    Key key,
    double scale = 1.0,
    this.frameBuilder,
    this.semanticLabel,
    this.excludeFromSemantics = false,
    this.width,
    this.height,
    this.color,
    this.colorBlendMode,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.centerSlice,
    this.matchTextDirection = false,
    this.gaplessPlayback = false,
    this.filterQuality = FilterQuality.low,
  }) : image = MemoryImage(bytes, scale: scale),
       loadingBuilder = null,
       assert(alignment != null),
       assert(repeat != null),
       assert(matchTextDirection != null),
       super(key: key);

2.Image属性说明

2.1 ImageProvider image

要显示的图片。

  1. AssetImage(‘assets/images/lake.jpg’): 获取来自assets的图片;
  2. NetworkImage(‘http://pic33.nipic.com/20131007/13639685_123501617185_2.jpg’):获取来自网络的图片
  3. FileImage(File(’/Users/maxlz/Desktop/StudyData/Flutter/flutterdemo/assets/images/lake.jpg’)):加载来自文件的图片
  4. 以下是一个加载来自内存中图片的例子:
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;

class ImageDemo extends StatefulWidget{
  @override
  _ImageDemoState createState() => _ImageDemoState();
}

class _ImageDemoState extends State<ImageDemo>{
  Uint8List bytes;
  @override
  void initState() {
    super.initState();
    rootBundle.load('assets/images/lake.jpg').then((data){
      setState(() {
        bytes = data.buffer.asUint8List();
      });
    });
  }
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Image(
              // image: AssetImage('assets/images/lake.jpg'),
              // image: NetworkImage('http://pic33.nipic.com/20131007/13639685_123501617185_2.jpg'),
              // image: FileImage(File('/Users/maxlz/Desktop/StudyData/Flutter/flutterdemo/assets/images/lake.jpg')),
              image: bytes == null ? null : MemoryImage(bytes),
              fit: BoxFit.cover,
              height: 200,
              width: 350,
            ),
          ],
        )
      ],
    );
  }
}

以上四种方式均可以使用对应的命名构造方法创建Image。

2.2 ImageFrameBuilder frameBuilder

可使用该属性在图片显示时添加动画,如下是一个图片淡入显示效果。当该属性与loadingBuilder属性同时存在时,该属性的result会作为child传入loadingBuilder中

Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Image(
              image: NetworkImage('http://pic33.nipic.com/20131007/13639685_123501617185_2.jpg'),
              frameBuilder: (context, child, frame, wasSynchronouslyLoaded){
                if (wasSynchronouslyLoaded){
                  return child;
                }
                return AnimatedOpacity(
                  child: child,
                  opacity: frame == null ? 0 : 1,
                  duration: const Duration(seconds: 4),
                  curve: Curves.easeOut,
                );
              },
             fit: BoxFit.cover,
              height: 200,
              width: 350,
            ),
          ],
        )
      ],
    );
  }

2.3 ImageLoadingBuilder loadingBuilder

可通过该属性在图片加载时显示一个widget,例如下面是一个图片加载过程中显示一个加载进度的示例:

Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Image(
              image: NetworkImage('http://pic33.nipic.com/20131007/13639685_123501617185_2.jpg'),
              loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent loadingProgress){
                if (loadingProgress == null)
                  return child;
                return Center(
                  child: CircularProgressIndicator(
                    value: loadingProgress.expectedTotalBytes != null
                  ? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes
                  : null,
                  ),
                );
              },
              fit: BoxFit.cover,
              height: 200,
              width: 350,
            ),
          ],
        )
      ],
    );
  }

2.4 double width

图片宽度

2.5 double height

图片高度

2.6 Color color

如果设置了color,则会使用[colorBlendMode]将此颜色与每个图像像素混合。

2.7 FilterQuality filterQuality

2.8 BlendMode colorBlendMode

将设置的颜色与图像按一定模式结合起来,BlendMode是个枚举类,有以下值:
*注意这里的源图像指的是图片,目标图像指的是color,空白的说明自己看源码注释吧

枚举值说明
clear清空源图像及目标图像
src清空图像,绘制目标图像
dst清空目标图像,绘制源图像
srcOver目标图像在源图像之上
dstOver目标图像在源图像之下
srcIn显示源图像
dstIn
srcOut
dstOut
srcATop
dstATop
xor
plus
modulate
screen
overlay
darken
lighten
colorDodge
colorBurn
hardLight
softLight
difference
exclusion
multiply将源图像和目标图像的组件相乘,包括alpha通道
hue取源图像的色调,目标图像的饱和度和亮度
saturation取源图像的饱和度,以及目标图像的色调和亮度
color取源图像的色调和饱和度,以及目标图像的亮度。
luminosity取源图像的亮度,目标图像的色调和饱和度

2.9 FilterQuality filterQuality

用于设置图像的过滤器质量,FilterQuality是个枚举类,有以下值:

  1. none
  2. low
  3. medium
  4. high

2.10 BoxFit fit

图像在已分配空间中的填充方式,BoxFit是枚举类,有以下值:

  1. fill:整个图片自动填充满区域,可能导致图片变形
  2. contain:图片原比例填充,可能导致已分配空间不能填满
  3. cover:常用值。图像不会变形,空间会被填充满,但图片显示可能不全
  4. fitWidth:按照宽度填充,图片不会变形
  5. fitHeight:按照高度填充,图片不会变形
  6. none:不处理
  7. scaleDown:将源文件对齐到目标框内(默认情况下,居中),如果需要,将源文件向下缩放,以确保源文件适合框内。

2.11 AlignmentGeometry alignment

控制图像在已分配空间中的对齐方式。

2.12 ImageRepeat repeat

控制图像填满空间的模式。

  1. ImageRepeat.repeat: 空白部分全部使用图片填充
  2. ImageRepeat.repeatX:只填充x轴方向的空白部分
  3. ImageRepeat.repeatY:只填充y轴方向的空白部分
  4. ImageRepeat.noRepeat:不填充空白

2.13 Rect centerSlice

待定…

2.14 bool matchTextDirection

是否在[TextDirection]方向上绘制图像。

2.15 bool gaplessPlayback

当ImageProvider改变时,设为true则继续显示旧图像,false则不显示任何内容

2.16 String semanticLabel

图像的语义描述,用于在Android上提供对讲图像描述,在iOS上提供画外音

2.17 bool excludeFromSemantics

是否将此图像从语义中排除

 类似资料: