🎃

【Flutter Widget基礎】Image

2024/08/28に公開

Image基礎

Imageの属性

  • flutter/material.dartをimportをすればImageウィジェットを利用可能になります。
  • dart.uiにもImageクラスがありますが、間違いないように注意が必要になります。
  • Image自体はステータスを持っているため、StatefulWidgetを継承しています。
class Image extends StatefulWidget {
  const Image({
    super.key,
    required this.image,
    this.frameBuilder,
    this.loadingBuilder,
    this.errorBuilder,
    this.semanticLabel,
    this.excludeFromSemantics = false,
    this.width,
    this.height,
    this.color,
    this.opacity,
    this.colorBlendMode,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.centerSlice,
    this.matchTextDirection = false,
    this.gaplessPlayback = false,
    this.isAntiAlias = false,
    this.filterQuality = FilterQuality.low,
  });

Imageの生成

Imageの生成には5つの方法があります。

  • const Image({Key key,@required this.image, //ImageProviderを経由して生成
  • Image.network( String src, { //リモートのリソース経由で生成
  • Image.file(File file, { //ファイル経由で生成
  • Image.asset(String name, //assetリソース経由で生成
  • Image.memory(Uint8List bytes, //メモリ経由で生成

そのなかに、assetリソース経由の生成する場合は、asset設定が必要になります。設定方法としては、lib/imagesに画像リソースをいれて、pubspec.yamlにasset宣言すれば下記のように利用可能になります。

Image.asset("images/usj.jpg", width: 200, height: 200)

よく利用するImage属性

Imageの幅と高さ

Imageの幅と高さを設定するにはImageに設定する方法と親Containerに入れる方法があります。
それぞれの設定例を見てみましょう(画像自体は1:1ではない)。

Imageに設定する方法

Image.asset("images/usj.jpg", width: 200, height: 200)

親Containerに設定する方法

Container(
    width: 200, 
    height: 200, 
    color: Colors.lightBlue, 
    child: Image.asset("images/usj.jpg"),),

Imageの表示様式(BoxFit)

BoxFit設定 効果
BoxFit.none 画像はスケーリングされず、元のサイズが維持されます。画像が親ウィジェットのサイズを超える場合、切り取られることがあります。
BoxFit.contain 画像のアスペクト比を保持しながら、親ウィジェットのサイズに収まるようにスケーリングします。
BoxFit.cover 画像のアスペクト比を保持しつつ、親ウィジェットを完全に覆うようにスケーリングします。画像の一部が切り取られることがあります。
BoxFit.fill 画像が親ウィジェットのサイズに合わせて引き伸ばされ、アスペクト比は無視されます。
BoxFit.fitHeight 画像のアスペクト比を保持しながら、親ウィジェットの高さに合わせてスケーリングします。画像の幅が親ウィジェットの幅を超える場合、切り取られることがあります。
BoxFit.fitWidth 画像のアスペクト比を保持しながら、親ウィジェットの幅に合わせてスケーリングします。画像の高さが親ウィジェットの高さを超える場合、切り取られることがあります。
BoxFit.scaleDown 親ウィジェットのサイズを超えた場合、画像のアスペクト比を保持しながらスケーリングします。親ウィジェットのサイズを超えていない場合はスケーリングしません。

各設定値を設定した後の効果を比較しましょう。

    var fitMode = [BoxFit.none, BoxFit.contain, BoxFit.cover,
      BoxFit.fill, BoxFit.fitHeight, BoxFit.fitWidth, BoxFit.scaleDown
    ];

    Color randomRGB() {
      Random random = Random();
      int r = 30 + random.nextInt(200);
      int g = 30 + random.nextInt(200);
      int b = 30 + random.nextInt(200);
      return Color.fromARGB(255, r, g, b);
    }

    form() {
      var imageList = <Widget>[];
      for (var fit in fitMode) {
        var img = Container(
            margin: const EdgeInsets.all(10),
            width: 150,
            height: 60,
            color: randomRGB(),
            child: Image(
              image: const AssetImage("images/usj.jpg"),
              fit: fit,
            ));

        imageList.add(Column(
          children: [img, Text(fit.toString())],
        ));
      }
      return imageList;
    }

    var imgBox = Wrap(
      children: form(),
    );

Imageの色と合成モード(colorとcolorBlendMode)

モードの設定値が多い為、各モードの詳細な説明は公式ドキュメントをご確認ください。こちらは表示の違いのみ比較させてください。

各設定値を設定した後の効果を比較しましょう。

    //blend mode
    var colorBlendMode = [  BlendMode.clear,BlendMode.src,BlendMode.dst,  BlendMode.srcOver,BlendMode.dstOver,BlendMode.srcIn,  BlendMode.dstIn,BlendMode.srcOut,BlendMode.dstOut,  BlendMode.srcATop,BlendMode.dstATop,BlendMode.xor,  BlendMode.plus, BlendMode.modulate,BlendMode.screen,  BlendMode.overlay,BlendMode.darken,BlendMode.lighten,  BlendMode.colorDodge,BlendMode.colorBurn,BlendMode.hardLight,  BlendMode.softLight,BlendMode.difference,BlendMode.exclusion,  BlendMode.multiply,BlendMode.hue,BlendMode.saturation,  BlendMode.color, BlendMode.luminosity,];

    formImagesColorBlendMode() {
      var imageList = <Widget>[];
      for (var mode in colorBlendMode) {
        var img = Container(
            margin: const EdgeInsets.all(5),
            width:50,
            height: 50,
            child: Image(
              image: const AssetImage("images/usj.jpg"),
              fit: BoxFit.contain,
              color: Colors.blue,
              colorBlendMode: mode,
            ));
        imageList.add(Column(children: <Widget>[
          img,
          Text(mode.toString().split(".")[1])
        ]));
      }
      return imageList;
    }

    var imageColorMode = Wrap(
      children: formImagesColorBlendMode(),
    );

Imageの配置(alignment)

既存の定義(center, centerLeftなど)がほとんどの要件に満たしていますが、細かく制御したい場合は独自でAlignmentを生成する方法もあります。

各設定値を設定した後の効果を比較しましょう。

    var alignments = [  Alignment.center,  Alignment.centerLeft, Alignment.centerRight,  Alignment.topCenter,Alignment.topLeft, Alignment.topRight,  Alignment.bottomCenter,Alignment.bottomLeft,Alignment.bottomRight,const Alignment(0.01,0.01),const Alignment(0.5,0.5)];
    Color randomRGB() {
      Random random = Random();
      int r = 30 + random.nextInt(200);
      int g = 30 + random.nextInt(200);
      int b = 30 + random.nextInt(200);
      return Color.fromARGB(255, r, g, b);
    }
    formImageAlignments() {
      var imageList = <Widget>[];
      for (var align in alignments) {
        var img = Container(
            margin: const EdgeInsets.all(7),
            width: 150,
            height: 60,
            color: randomRGB(),
            child: Image(
              image: const AssetImage("images/usj_hari.jpg"),
              alignment: align,
            ));

        imageList.add(Column(
          children: [img, Text(align.toString())],
        ));
      }
      return imageList;
    }

    var imageAlignments = Wrap(
      children: formImageAlignments(),
    );

その他

円形画像の生成(プロフィール画像)

円形画像を生成するには3つの方法があります。どちらも同じように円形画像を生成できますが、多くはCircleAvatarを利用します。

  • BoxDecorationを利用
  Container(
     height: 100,
     width: 100,
     decoration: BoxDecoration(
         color: Colors.blue,
         borderRadius: BorderRadius.circular(50),
         image: const DecorationImage(image:AssetImage("images/usj.jpg"),fit: BoxFit.cover)
      ),
  )
  • ClipOvalを利用
  ClipOval(
     child: Image.asset("images/usj.jpg",
     width: 100,
     height: 100,
     fit: BoxFit.cover),
  ),
  • CircleAvatarを利用
  CircleAvatar(
       backgroundImage: AssetImage("images/usj.jpg"),
       radius: 50.0,
  ),

Discussion