Flutter入门: Image 详解

Auth:老猿𝕏𝕏       Date:2024/06/16       Cat:编程       Word:共9789字

当前版本 Flutter 3.19.5

前言

Image 是 Flutter 中用于显示图像的组件。它支持多种图像来源,包括网络图像、资源图像、文件系统图像以及内存图像。Image 组件提供了多种构造函数,如 Image.network、Image.asset、Image.file 和 Image.memory,以便于从不同的来源加载图像。它还支持多种图像调整选项,如缩放、裁剪、对齐和颜色滤镜,使开发者可以灵活地在应用中展示图像内容。 Image API

构造函数

Image

实现

const Image(
  {
    Key? key,
    required ImageProvider<Object> image,
    ImageFrameBuilder? frameBuilder,
    ImageLoadingBuilder? loadingBuilder,
    ImageErrorWidgetBuilder? errorBuilder,
    String? semanticLabel,
    bool excludeFromSemantics = false,
    double? width,
    double? height,
    Color? color,
    Animation<double>? opacity,
    BlendMode? colorBlendMode,
    BoxFit? fit,
    AlignmentGeometry alignment = Alignment.center,
    ImageRepeat repeat = ImageRepeat.noRepeat,
    Rect? centerSlice,
    bool matchTextDirection = false,
    bool gaplessPlayback = false,
    bool isAntiAlias = false,
    FilterQuality filterQuality = FilterQuality.low
  }
)

示例

Flutter入门:  Image 详解 - 第1张图片

const Image(
  image: AssetImage('images/logo.png'),
  width: 200,
),

Image.asset

显示从资源包中获取的ImageStream

实现

Image.asset(
  String name,
  {
    Key? key,
    AssetBundle? bundle,
    ImageFrameBuilder? frameBuilder,
    ImageErrorWidgetBuilder? errorBuilder,
    String? semanticLabel,
    bool excludeFromSemantics = false,
    double? scale,
    double? width,
    double? height,
    Color? color,
    Animation<double>? opacity,
    BlendMode? colorBlendMode,
    BoxFit? fit,
    AlignmentGeometry alignment = Alignment.center,
    ImageRepeat repeat = ImageRepeat.noRepeat,
    Rect? centerSlice,
    bool matchTextDirection = false,
    bool gaplessPlayback = false,
    bool isAntiAlias = false,
    String? package,
    FilterQuality filterQuality = FilterQuality.low,
    int? cacheWidth,
    int? cacheHeight
  }
)

示例

显示 pubspec.yaml文件中定义的图片

// 显示图片
Image.asset(
  'images/logo.png',
  width: 200,
)

// pubspec.yaml
flutter:
  assets:
    - images/logo.png

自动匹配设备屏幕像素比,在设备像素比为 2.0 的屏幕上,将呈现 images/2x/logo.png 文件

// 显示图片
Image.asset(
  'images/logo.png',
  width: 200,
)
// pubspec.yaml
flutter:
  assets:
    - images/logo.png
    - images/2x/logo.png
    - images/3.5x/logo.png

显示第三方包中的图片

Image.asset(
  'images/logo.png',
  width: 200,
  package: 'my_app',
)

Image.file

用于从本地文件系统加载图像。通常用于加载设备存储中的图像,例如用户通过相机或图库选择的照片,应该指定宽度和高度参数,或者应该将小部件放置在设置了严格布局约束的上下文中。否则,图像尺寸将随着图像的加载而改变

实现

Image.file(
  File file,
  {
    Key? key,
    double scale = 1.0,
    ImageFrameBuilder? frameBuilder,
    ImageErrorWidgetBuilder? errorBuilder,
    String? semanticLabel, // 语义标签
    bool excludeFromSemantics = false,
    double? width,
    double? height,
    Color? color,
    Animation<double>? opacity,
    BlendMode? colorBlendMode, // 颜色混合模式
    BoxFit? fit, // 图像的填充模式
    AlignmentGeometry alignment = Alignment.center, // 图像的对齐
    ImageRepeat repeat = ImageRepeat.noRepeat, // 图像的重复模式
    Rect? centerSlice,
    bool matchTextDirection = false,
    bool gaplessPlayback = false,
    bool isAntiAlias = false, // 是否启用抗锯齿
    FilterQuality filterQuality = FilterQuality.low, // 图像的渲染质量
    int? cacheWidth,
    int? cacheHeight
  }
)

示例

File? image;

GestureDetector(
  onTap: () async{
    final ImagePicker picker = ImagePicker();
    final XFile? image = await picker.pickImage(source: ImageSource.gallery);

    if (image != null) {
      setState(() {
        this.image = File(image.path);
      });
    }
  },
  child: Text('点击加载图片'),
)

Image.file(image!)

Image.memory

用于从内存加载图像

实现

Image.memory(
  Uint8List bytes,
  {
    Key? key,
    double scale = 1.0,
    ImageFrameBuilder? frameBuilder,
    ImageErrorWidgetBuilder? errorBuilder,
    String? semanticLabel,
    bool excludeFromSemantics = false,
    double? width,
    double? height,
    Color? color,
    Animation<double>? opacity,
    BlendMode? colorBlendMode,
    BoxFit? fit,
    AlignmentGeometry alignment = Alignment.center,
    ImageRepeat repeat = ImageRepeat.noRepeat,
    Rect? centerSlice,
    bool matchTextDirection = false,
    bool gaplessPlayback = false,
    bool isAntiAlias = false,
    FilterQuality filterQuality = FilterQuality.low,
    int? cacheWidth,
    int? cacheHeight
  }
)

示例

Uint8List? image;

GestureDetector(
  onTap: () async{
    final ImagePicker picker = ImagePicker();
    final XFile? image = await picker.pickImage(source: ImageSource.gallery);
    final Uint8List? imageBytes = await image?.readAsBytes();

    if (image != null) {
      setState(() {
        this.image = imageBytes;
      });
    }
  },
  child: Text('点击加载图片'),
)

Image.memory(image!)

Image.network

用于从网络加载图像

实现

Image.network(
  String src,
  {
    Key? key,
    double scale = 1.0,
    ImageFrameBuilder? frameBuilder,
    ImageLoadingBuilder? loadingBuilder,
    ImageErrorWidgetBuilder? errorBuilder,
    String? semanticLabel,
    bool excludeFromSemantics = false,
    double? width,
    double? height,
    Color? color,
    Animation<double>? opacity,
    BlendMode? colorBlendMode,
    BoxFit? fit,
    AlignmentGeometry alignment = Alignment.center,
    ImageRepeat repeat = ImageRepeat.noRepeat,
    Rect? centerSlice,
    bool matchTextDirection = false,
    bool gaplessPlayback = false,
    FilterQuality filterQuality = FilterQuality.low,
    bool isAntiAlias = false,
    Map<String, String&gt? headers,
    int? cacheWidth,
    int? cacheHeight
  }
)

示例

Image.network(
  'https://www.baidu.com/img/flexible/logo/pc/result.png',
  width: 200,
),

属性

alignment

定义图像的对齐方式,默认值为 Alignment.center 也可以自定义 Alignment( -1.0, -1.0) 将图像与其布局边界的左上角对齐,而Alignment ( 1.0 , 1.0) 将图像的右下角与其布局边界的右下角对齐 其它可选值如下

bottomCenter
bottomLeft
bottomRight
center
centerLeft
centerRight
topCenter
topLeft
topRight

实现

AlignmentGeometry alignment

示例

Flutter入门:  Image 详解 - 第2张图片

Container(
  decoration: BoxDecoration(
    border: Border.all(color: Colors.red, width: 10),
  ),
  width: 500,
  height: 400,
  child: Image.network(
    'https://www.baidu.com/img/flexible/logo/pc/result.png',
    width: 200,
    alignment: Alignment.bottomRight,
  ),
),

centerSlice

九宫格图像的中心切片。 中心切片内的图像区域将水平和垂直拉伸,以使图像适合其目标。中心切片上方和下方的图像区域将仅水平拉伸,中心切片左侧和右侧的图像区域将仅垂直拉伸。

实现

Rect? centerSlice

示例

Flutter入门:  Image 详解 - 第3张图片

Container(
  decoration: BoxDecoration(
    border: Border.all(color: Colors.red, width: 10),
  ),
  width: 500,
  height: 400,
  child: Image.network(
    'https://www.baidu.com/img/flexible/logo/pc/result.png',
    width: 200,
    centerSlice: Rect.fromLTWH(30, 30, 10, 10),
  ),
),

color

如果非空,则使用colorBlendMode将此颜色与每个图像像素混合。

实现

Color? color;

示例

Flutter入门:  Image 详解 - 第4张图片

Container(
  decoration: BoxDecoration(
    border: Border.all(color: Colors.red, width: 10),
  ),
  width: 500,
  height: 400,
  child: Image.network(
    'https://www.baidu.com/img/flexible/logo/pc/result.png',
    width: 200,
    color: Colors.purple,
  ),
),

colorBlendMode

用于将颜色与此图像结合。默认值为BlendMode.srcIn。就混合模式而言,颜色是源,而此图像是目标。 其它可选值如下,详情见 https://api.flutter.dev/flutter/dart-ui/BlendMode.html#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
hue
saturation
color
luminosity

实现

BlendMode? colorBlendMode;

示例

Flutter入门:  Image 详解 - 第5张图片

Container(
  decoration: BoxDecoration(
    border: Border.all(color: Colors.red, width: 10),
  ),
  width: 500,
  height: 400,
  child: Image.network(
    'https://www.baidu.com/img/flexible/logo/pc/result.png',
    width: 200,
    color: Colors.purple,
    colorBlendMode: BlendMode.colorBurn,
  ),
),

errorBuilder

当加载图像发生错误时调用此回调。

实现

ImageErrorWidgetBuilder? errorBuilder

示例

Image.network(
  'https://www.baidu.com/xxxxx.png',
  width: 200,
  errorBuilder: (BuildContext context, Object exception,
          StackTrace? stackTrace) =>
      const Text('加载失败'),
),

excludeFromSemantics

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

实现

bool excludeFromSemantics

示例

Image.network(
  'https://www.baidu.com/img/flexible/logo/pc/result.png',
  width: 200,
  excludeFromSemantics: true,
),

filterQuality

图像的过滤质量。默认值是FilterQuality.low。 其它可选值如下

none
low
medium
high

实现

FilterQuality filterQuality

示例

Image.network(
  'https://www.baidu.com/img/flexible/logo/pc/result.png',
  width: 200,
  filterQuality: FilterQuality.high,
),

fit

图像的填充模式。默认值是BoxFit.none 其它可选值如下

fill
contain
cover
fitWidth
fitHeight
none

实现

BoxFit fit

示例

Flutter入门:  Image 详解 - 第6张图片

Container(
  decoration: BoxDecoration(
    border: Border.all(color: Colors.red, width: 10),
  ),
  width: 500,
  height: 400,
  child: Image.network(
    'https://www.baidu.com/img/flexible/logo/pc/result.png',
    width: 200,
    fit: BoxFit.fill,
  ),
),

frameBuilder

在每一帧图像加载时自定义构建逻辑。通过使用 frameBuilder,你可以实现诸如加载动画、占位符、或其他自定义效果 传递一个回调函数给 frameBuilder 属性。 wasSynchronouslyLoaded 为 true 时,图像是同步加载的,直接返回图像。 使用 AnimatedOpacity 来实现淡入效果,当 frame 为 null 时(即图像未加载完成),设置不透明度为 0;否则设置为 1。 AnimatedOpacity 的 duration 设置为 1 秒,使用 Curves.easeOut 曲线,实现平滑的淡入效果。

实现

ImageFrameBuilder? frameBuilder

示例

Flutter入门:  Image 详解 - 第7张图片

Image.network(
  'https://www.baidu.com/img/flexible/logo/pc/result.png',
  width: 200,
  frameBuilder: (
    BuildContext context,
    Widget child,
    int? frame,
    bool wasSynchronouslyLoaded,
  ) {
    if (wasSynchronouslyLoaded) {
      return child;
    }
    return AnimatedOpacity(
      child: Container(
        decoration: BoxDecoration(
          border: Border.all(color: Colors.red, width: 10),
        ),
        padding: const EdgeInsets.all(8.0),
        child: child,
      ),
      opacity: frame == null ? 0 : 1,
      duration: const Duration(seconds: 1),
      curve: Curves.easeOut,
    );
  },
),

gaplessPlayback

控制图像在重新加载时是否无缝播放。它解决了在某些情况下,当图像源更改或重新加载时出现的闪烁问题,默认值: false

实现

bool gaplessPlayback

示例

Image.network(
  'https://www.baidu.com/img/flexible/logo/pc/result.png',
  width: 200,
  gaplessPlayback: true,
),

width/height

图像的 宽度 和 高度

实现

double height

示例

Image.network(
  'https://www.baidu.com/img/flexible/logo/pc/result.png',
  width: 200,
  height: 100,
),

image

显示的图像

实现

Image image

示例

Image(
  image: NetworkImage('https://www.baidu.com/img/flexible/logo/pc/result.png'),
),

isAntiAlias

是否启用抗锯齿

实现

bool isAntiAlias

示例

Image.network(
  'https://www.baidu.com/img/flexible/logo/pc/result.png',
  width: 200,
  isAntiAlias: true,
),

loadingBuilder

用于在图像加载期间执行自定义逻辑或显示自定义的加载指示器。它允许在图像加载过程中处理不同的加载状态,比如加载中、加载成功或加载失败

实现

ImageLoadingBuilder? loadingBuilder

示例

Image.network(
  'https://www.baidu.com/img/flexible/logo/pc/result.png',
  width: 200,
  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,
      ),
    );
  },
),

matchTextDirection

用于控制图像是否在不同的文本方向(从左到右或从右到左)下自动翻转。这在支持国际化应用时特别有用,因为某些图像可能需要根据文本方向进行镜像翻转

实现

bool matchTextDirection

示例

Flutter入门:  Image 详解 - 第8张图片

Directionality(
  textDirection: TextDirection.rtl,
  child: Image.network(
    'https://www.baidu.com/img/flexible/logo/pc/result.png',
    width: 200,
    matchTextDirection: true,
  ),
),

opacity

用于控制图像的透明度 #### 实现

Animation<double>? opacity;

示例

Flutter入门:  Image 详解 - 第9张图片

Image.network(
  'https://www.baidu.com/img/flexible/logo/pc/result.png',
  width: 200,
  opacity: const AlwaysStoppedAnimation(0.5),
),

repeat

用于控制图像是否重复

实现

ImageRepeat repeat

示例

Flutter入门:  Image 详解 - 第10张图片

Container(
  decoration: BoxDecoration(
    border: Border.all(color: Colors.red, width: 10),
  ),
  width: 500,
  height: 400,
  child: Image.network(
    'https://www.baidu.com/img/flexible/logo/pc/result.png',
    width: 200,
    repeat: ImageRepeat.repeatY,
  ),
),

semanticLabel

用于控制图像的语义标签

实现

String? semanticLabel

示例

Image.network(
  'https://www.baidu.com/img/flexible/logo/pc/result.png',
  width: 200,
  semanticLabel: '图片',
),

《Flutter入门: Image 详解》留言数:0

发表留言