flutter:图片组件Image

  1. Image 构造函数
    1. 默认构造函数
    2. Image.asset
    3. Image.network
    4. Image.file
    5. Image.memory
    6. 关系
  • colorBlendMode 混合参数
  • fit 图片大小适配
  • ImageProvider 图片对象
  • Image 构造函数

    默认构造函数

    Image 是一个图像的 Widget ,提供了一些类方法来快捷使用来自内存、本地、网络、Assets 的图片

    以下是他的定义:

    //通过ImageProvider来加载图片
    const Image({
        Key key,
        // ImageProvider,图像显示源
        @required this.image,
        this.semanticLabel,
        this.excludeFromSemantics = false,
        //显示宽度
        this.width,
        //显示高度
        this.height,
        //图片的混合色值
        this.color,
        //混合模式
        this.colorBlendMode,
        //缩放显示模式
        this.fit,
        //对齐方式
        this.alignment = Alignment.center,
        //重复方式
        this.repeat = ImageRepeat.noRepeat,
        //当图片需要被拉伸显示的时候,centerSlice定义的矩形区域会被拉伸,类似.9图片
        this.centerSlice,
        //类似于文字的显示方向
        this.matchTextDirection = false,
        //图片发生变化后,加载过程中原图片保留还是留白
        this.gaplessPlayback = false,
        //图片显示质量
        this.filterQuality = FilterQuality.low,
      })
    

    Image.asset

    用于加载 应用资源目录(assets)里的图片。

    以下是他的定义:

    // 加载本地资源图片,例如项目内资源图片
    // 需要把图片路径在pubspec.yaml文件中声明一下,如:
    // assets:
    //      - packages/fancy_backgrounds/backgrounds/background1.png
    // 封装类有:AssetImage、ExactAssetImage
    Image.asset(
        //文件名称,包含路径
        String name,
      {
        Key key,
        // 用于访问资源对象
        AssetBundle bundle,
        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,
      })
    

    特点:

    • 需要在 pubspec.yaml 里声明:

      flutter:
        assets:
          - assets/images/logo.png
      
    • 打包进应用,不依赖网络。

    • 常用于 UI 图标、背景图等固定资源。

    Image.asset(
      'assets/images/logo.png',
      width: 100,
      height: 100,
      fit: BoxFit.cover,
    )
    

    Image.network

    用于加载 网络图片

    以下是他的定义:

    // 加载网络图片,封装类:NetworkImage
    Image.network(
        //路径
        String src,
       {
        Key key,
        //缩放
        double scale = 1.0,
        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,
      })
    

    特点:

    • 适合显示动态内容(比如用户头像、商品图片)
    • 需要网络请求,第一次可能会有延迟。
    • 通常要配合 缓存插件(如 cached_network_image)使用,避免每次都重新下载。
    Image.network(
      'https://example.com/logo.png',
      width: 100,
      height: 100,
      fit: BoxFit.cover,
    )
    

    Image.file

    用于加载 本地文(用户的)件系统里的图片。

    以下是他的定义:

    // 加载本地File文件图片,封装类:FileImage
    Image.file(
        //File对象
        File file,
      {
        Key key,
        double scale = 1.0,
        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,
      })
    

    特点:

    • 图片必须真实存在于本地路径。
    • 适合加载用户拍的照片、下载的图片等。
    • 可能需要文件权限(Android 需要存储访问权限)。
    import 'dart:io';
    
    Image.file(
      File('/storage/emulated/0/DCIM/photo.jpg'),
      width: 100,
      height: 100,
      fit: BoxFit.cover,
    )
    

    Image.memory

    用于加载 内存中的二进制数据(Uint8List

    // 加载Uint8List资源图片/从内存中获取图片显示
    // 封装类:MemoryImage
    Image.memory(
        // Uint8List资源图片
        Uint8List bytes,
      {
        Key key,
        double scale = 1.0,
        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,
      })
    

    特点:

    • 直接渲染二进制数据。
    • 常用于 Base64 图片、加密图片、本地缓存的二进制图片
    • 灵活但需要自己管理数据来源。
    import 'dart:typed_data';
    
    Uint8List bytes = ...; // 可能来自网络/数据库/压缩后的图片数据
    Image.memory(
      bytes,
      width: 100,
      height: 100,
      fit: BoxFit.cover,
    )
    

    关系

    Image.assetImage.networkImage.fileImage.memory 其实都是对 Image 默认构造函数 的封装,分别对应不同的 ImageProvider

    • Image.asset → 内部用 AssetImage
    • Image.network → 内部用 NetworkImage
    • Image.file → 内部用 FileImage
    • Image.memory → 内部用 MemoryImage

    等价写法对比:它们效果完全一样,只是写法不同。

    // 方式 1:用 Image.asset
    Image.asset('assets/images/logo.png')
    
    // 方式 2:用 Image + AssetImage
    Image(image: AssetImage('assets/images/logo.png'))
    
    构造函数 数据来源 使用场景
    Image.asset 应用打包资源 App 内置图标、背景、装饰图
    Image.network 网络 URL 头像、商品图、新闻配图
    Image.file 本地文件 相册照片、下载文件
    Image.memory 内存二进制数据 Base64 图片、缓存字节流

    colorBlendMode 混合参数

    在 Flutter 的 Image 组件中,有一个参数 colorBlendMode,它的作用就是 定义 color 和图片如何混合(Blend)

    Image 有两个相关参数:

    • color:要叠加在图片上的颜色。
    • colorBlendMode:颜色和图片如何叠加的规则。

    枚举 BlendMode 定义

    enum BlendMode {
      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 解释 效果举例(假设图片是 A,颜色是 B)
    Clear 清空 全部变透明,什么都不显示
    Src 仅显示源(颜色 B) 图片完全被颜色覆盖,只保留 B
    Dst 仅显示目标(图片 A) 忽略颜色,只显示图片本身
    SrcOver 源覆盖在目标之上 B 叠加在 A 上(最常用的「覆盖」效果)
    DstOver 目标覆盖在源之上 A 叠加在 B 上,颜色在下层
    SrcIn 源在目标的交集区域显示 B 只在 A 的不透明区域可见(图标染色常用 ✅)
    DstIn 目标在源的交集区域显示 A 只在 B 的不透明区域可见
    SrcOut 源在目标以外显示 B 只在 A 透明的地方显示
    DstOut 目标在源以外显示 A 只在 B 透明的地方显示
    SrcATop 源在目标之上,但裁剪到目标的范围 B 显示在 A 的区域内,A 仍然显示
    DstATop 目标在源之上,但裁剪到源的范围 A 显示在 B 的区域内,B 仍然显示
    Xor 仅显示不重叠部分 显示 A 和 B 不相交的部分
    Darken 取较暗值 对每个像素,取 A 和 B 较暗的结果
    Lighten 取较亮值 对每个像素,取 A 和 B 较亮的结果
    Multiply 颜色相乘 结果更暗,类似 Photoshop 的「正片叠底」
    Screen 相乘的反效果 结果更亮,类似 Photoshop 的「滤色」
    class ComponentPage extends StatelessWidget {
      const ComponentPage({super.key});
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          // appBar: AppBar(title: const Text('组件')),
          body: Column(
            children: [
              Image.asset(
                AssetsImages.welcomePng,
                color: Colors.black,
                // 颜色混合模式, dstOver 表示在目标图像上叠加源图像
                colorBlendMode: BlendMode.dstOver,
              ),
            ],
          ),
        );
      }
    }
    

    fit 图片大小适配

    名称 说明
    fill 图片按照指定的大小在 Image 中显示,拉伸显示图片,不保持原比例,填满 Image。
    contain 以原图正常显示为目的,如果原图大小大于 Image 的 size,就按照比例缩小原图的宽高,居中显示在 Image 中。如果原图 size 小于 Image 的 size,则按比例拉升原图的宽和高,填充 Image 一边并居中显示。
    cover 以原图填满 Image 为目的,如果原图 size 大于 Image 的 size,按比例缩小,居中显示在 Image 上。如果原图 size 小于 Image 的 size,则按比例拉升原图的宽和高,填充 Image 居中显示。
    fitWidth 以原图正常显示为目的,如果原图宽大小大于(小于)Image 的宽,就缩小(放大)原图的宽与 Image 一致,居中显示在 Image 中。
    fitHeight 以原图正常显示为目的,如果原图高大小大于(小于)Image 的高,就缩小(放大)原图的高与 Image 一致,居中显示在 Image 中。
    none 保持原图的大小,显示在 Image 的中心。当原图的 size 大于 Image 的 size 时,多出来的部分被截掉。
    scaleDown 以原图正常显示为目的,如果原图大小大于 Image 的 size,就按照比例缩小原图的宽高,居中显示在 Image 中。如果原图 size 小于 Image 的 size,则不做处理居中显示图片。
    class ComponentPage extends StatelessWidget {
      const ComponentPage({super.key});
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          // appBar: AppBar(title: const Text('组件')),
          body: Column(
            children: [
              // 设定 Image 的size
              SizedBox(
                height: 200,
                width: 100,
                child: Image.asset(
                  AssetsImages.welcomePng,
                  color: Colors.black,
                  // 颜色混合模式, dstOver 表示在目标图像上叠加源图像
                  colorBlendMode: BlendMode.dstOver,
                  // 图片填充方式, cover 表示裁剪并缩放以填满整个容器
                  fit: BoxFit.cover,
                ),
              ),
            ],
          ),
        );
      }
    }
    

    ImageProvider 图片对象

    Image 组件的 image 参数是一个 ImageProvider, 这样的设计好处是你的图片对象可以来自于各种方式

    ImageProvider 是一个抽象类,实现类有 AssetImageFileImageMemoryImageNetWorkImage

    import 'package:flutter/material.dart';
    
    class ImagesPage extends StatelessWidget {
      const ImagesPage({Key? key}) : super(key: key);
    
      // ImageProvider
      Widget _buildImageProvider() {
        return const Image(
          image: AssetImage('assets/images/welcome.png'),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(child: _buildImageProvider()),
        );
      }
    }
    

    ×

    喜欢就点赞,疼爱就打赏