[Flutter combat] Picture components and four major cases

Posted Jun 16, 202011 min read

Guide for Lao Meng:Hello everyone, this is the third in a series of [Flutter combat]articles. This article explains the picture component. Image has many advanced usages, and I hope it will help you.

The picture component is one of the basic components of Flutter, and it is as essential as the text component. The picture component contains two components, Image and Icon. In essence, Icon is not a picture component, but its appearance is similar to that of a picture.

In the project, it is recommended to use the Icon component first. Icon is essentially a font, but it does not display text, but an icon, and the Image component first decodes the image through the image decoder, so Icon has the following advantages:

  • Normally, the icon is smaller than the picture, which significantly reduces the size of the App package.
  • The icon will not be distorted or blurred. For example, if a 20x20 picture is rendered on a 200x200 screen, the picture will be distorted or blurred, while the icon is a vector illustration, it will not be distorted, just like the font.
  • Multiple icons can be stored in a file for easy management.
  • Common to all platforms.

Image

The Image component is used to display pictures. The source of the picture can be the picture on the network, the project, or the picture on the device.

Load network image:

Image.network(
  'http://pic1.win4000.com/pic/c/cf/cdc983699c.jpg',

)

Load the pictures in the project:

First copy the pictures to the project. Normally, copy them to the assets/images/ directory. The assets/images/ directory is created manually. New projects do not have this directory by default.

Set the pubspec.yaml configuration file:

assets:
  -assets/images/

Or specify the name of the specific picture:

assets:
  -assets/images/aa.jpg

Usually, the first method is used, because there will be many pictures, it is too cumbersome to add one to configure one here.

Note:The space problem in front of assets can easily cause compilation exceptions. The correct format is as follows:

Load picture:

Image.asset('assets/images/aa.jpg')

Load the picture on the device:

To load the pictures on the device(mobile phone), you first need to obtain the path of the device picture. Because the path of different platforms is different, the path must be obtained by native support. If you understand the native(Android and iOS) development, you can directly use MethodChannel* *Obtaining the path. If you don’t understand native(Android and iOS) development, you can use a third-party plug-in to obtain the path. Here is recommendedOfficial path_provider **.

Load the picture on the device:

Image.file(File('path'))

Set the size of the picture:

Image.asset('assets/images/aa.jpg',width:100,height:200,),

When the size of the Image and the size of the image do not match, you need to set the fill mode fit and set the component size to 150x150,

Container(
  color:Colors.red.withOpacity(.3),
  child:Image.asset('assets/images/aa.jpg',width:150,height:150),

)

It can be seen that there are blank areas(light red filled areas) on the left and right sides of the picture. If you want the picture to fill the entire area, set as follows:

Container(
  color:Colors.red.withOpacity(.3),
  child:Image.asset('assets/images/aa.jpg',width:150,height:150,fit:BoxFit.fill,),

)

Although the image fills the entire area, the image is distorted, stretching the image proportionally until both sides are full of the area:

Container(
  color:Colors.red.withOpacity(.3),
  child:Image.asset('assets/images/aa.jpg',width:150,height:150,fit:BoxFit.cover,),

)

At this point, the picture is not distorted and the area is filled on both sides, but the picture is partially cropped.

The fit parameter is to set the filling method, and its value is introduced as follows:

  • fill:full fill, the aspect ratio may change.
  • contain:Stretched proportionally until one side is filled.
  • cover:stretched proportionally until both sides are filled, at this time one side may be out of range.
  • fitWidth:proportionally stretched, full width filled.
  • fitHeight:proportional stretch, high fill.
  • none:When the component is smaller than the picture, it is not stretched and intercepted beyond the range.
  • scaleDown:When the component is smaller than the picture, the picture is proportionally reduced, the effect is the same as contain.

The cut of BoxFit.none is related to alignment, centered by default,

Image.asset(
  'assets/images/aa.jpg',
  width:150,
  height:150,
  fit:BoxFit.none,
  alignment:Alignment.centerRight,

),

The original picture is on the left.

Set the alignment:

Container(
  color:Colors.red.withOpacity(.3),
  child:Image.asset(
    'assets/images/aa.jpg',
    width:150,
    height:150,
    alignment:Alignment.centerLeft,
 ),

),

color and colorBlendMode are used to mix colors and colors. colorBlendMode indicates a blending mode. There are more blending modes described below. You can browse it once. This property can be used for simple filter effects.

  • clear:clear the source image and the target image.
  • color:Get the hue and saturation of the source image and the luminosity of the target image.
  • colorBurn:Divide the reciprocal of the target by the source, and then reciprocate the result.
  • colorDodge:Divide the target by the reciprocal of the source.
  • darken:The source image and target image are synthesized by selecting the minimum value from each color channel.
  • difference:subtract the smaller value from the larger value of each channel. Synthetic black has no effect. Synthesizing white inverts the color of another image.
  • dst:Only draw the target image.
  • dstATop:The target image is synthesized to the source image, but only at the position overlapping with the source image.
  • dstIn:Display the target image, but only display the position where the two images overlap. The source image is not rendered, only treated as a mask. The color channel of the source will be ignored, only the opacity will work.
  • dstOut:Display the target image, but only display the position where the two images do not overlap. The source image is not rendered, only treated as a mask. The color channel of the source will be ignored, only the opacity will work.
  • dstOver:Synthesize the source image under the target image.
  • exclusion:subtract two times the product of the two images from the sum of the two images.
  • hardLight:After adjusting the composition of the source image and the target image to make it fit the source image, multiply them.
  • hue:Get the hue of the source image, and the saturation and luminosity of the target image.
  • lighten:The source image and the target image are synthesized by selecting the maximum value from each color channel.
  • luminosity:Get the brightness of the source image, and the hue and saturation of the target image.
  • modulate:Multiply the color components of the source image and the target image.
  • multiply:Multiply the components of the source image and the target image, including the alpha channel.
  • overlay:After adjusting the components of the source image and the target image to make them fit the target, multiply them.
  • plus:Sum the components of the source image and the target image.
  • saturation:Get the saturation of the source image and the hue and brightness of the target image.
  • screen:Multiply the inverse values ​​of the components of the source image and the target image, and then inverse the result.
  • softLight:Use colorDodge for source values ​​below 0.5, and use colorBurn for source values ​​above 0.5.
  • src:Place the target image and only draw the source image.
  • srcATop:Synthesize the source image to the target image, but only at the position overlapping with the target image.
  • srcIn:Display the source image, but only display the position where the two images overlap. The target image is not rendered, only treated as a mask. The color channel of the target will be ignored, only the opacity will work.
  • srcOut:Display the source image, but only display the position where the two images do not overlap.
  • srcOver:Synthesize the source image to the target image.
  • xor:Apply the bitwise XOR operator to the source and target images.

Is it like reading it or not, and not even understand it?Normal, it is estimated that only those who have learned the visual algorithm can understand it, let's look at the effect of each attribute directly:

repeat means that when the component has a free position, the picture will be displayed repeatedly

Image.asset(
  'assets/images/aa.jpg',
  width:double.infinity,
  height:150,
  repeat:ImageRepeat.repeatX,

)

The repeated patterns are:

  • repeat:Both x and y directions are full.
  • repeatX:x direction is full.
  • repeatY:full in y direction.
  • noRepeat:Do not repeat.

When matchTextDirection is set to true, the drawing direction of the picture is the direction set by TextDirection, and its parent component must be Directionality:

Directionality(
    textDirection:TextDirection.rtl,
    child:Image.asset(
      'assets/images/logo.png',
      height:150,
      matchTextDirection:true,
   )),

The left side is the original image, the effect is left and right mirror image.

filterQuality indicates the quality of the drawn image, from high to low:high->medium->low->none. The higher the effect, the better, the smoother, of course, the greater the performance loss, the default is low, if you find that the picture is jagged, you can set this parameter.

Call back frameBuilder when loading a picture. When this parameter is null, this control will be displayed after the picture is loaded, and it will be blank when it is not loaded, especially when the network picture is loaded. Therefore, this parameter can be used to handle the transition effect of displaying the placeholder image and loading the image when the image is loaded, such as the fade-in and fade-out effect.

The following case is the effect of fade in and fade out:

Image.network(
  'https://flutter.github.io/assets-for-api-docs/assets/widgets/puffin.jpg',
  frameBuilder:(BuildContext context, Widget child, int frame,
      bool wasSynchronouslyLoaded) {
    if(wasSynchronouslyLoaded) {
      return child;
    }
    return AnimatedOpacity(
      child:child,
      opacity:frame == null? 0:1,
      duration:const Duration(seconds:2),
      curve:Curves.easeOut,
   );
  },

)

The loadingBuilder parameter is more fine-grained than the frameBuilder control, and you can get the picture loading progress. The following example shows the loading progress bar:

Image.network(
    'https://flutter.github.io/assets-for-api-docs/assets/widgets/puffin.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,
   ),
 );
})

centerSlice is used for .9 images, and .9 images are used to stretch specific areas of the picture. The area(Rect) set by centerSlice is the stretched area. The .9 picture is usually used in scenes where the control size and aspect ratio are not fixed, such as chat background image.

Container(
    width:250,
    height:300,
    decoration:BoxDecoration(
        image:DecorationImage(
            centerSlice:Rect.fromLTWH(20, 20, 10, 10),
            image:AssetImage(
              'assets/images/abc.jpg',
           ),
            fit:BoxFit.fill))),

The top is the original image, and the bottom is the stretched image.

When used, there is a high probability that the following abnormalities will occur:

This is because the image is larger than the size of the component. If you use the centerSlice attribute, the image must be smaller than the size of the component. In general, the size of the .9 image is very small.

Icon

Icon is an icon component, Icon does not have interactive properties, if you want to interact, you can use IconButton.

Icon(Icons.add),

Set the size and color of the icon:

Icon(
  Icons.add,
  size:40,
  color:Colors.red,

)

The black color above is the default size and color.

Icons.add is an icon provided by the system. When creating a Flutter project, the default configuration in pubspec.yaml is as follows:

All the icons have been defined in Icons, you can view them directly in the source code, or you can go to Official website to view all icons .

The effects of all icons are as follows:

Case

Chat background(.9 picture realization)

Container(
  width:200,
  padding:EdgeInsets.only(left:8, top:8, right:20, bottom:8),
  decoration:BoxDecoration(
      image:DecorationImage(
          centerSlice:Rect.fromLTWH(20, 20, 1, 1),
          image:AssetImage(
            'assets/images/chat.png',
         ),
          fit:BoxFit.fill)),
  child:Text('Lao Meng, focus on sharing Flutter technology and application combat.'
      'Lao Meng, focus on sharing Flutter technology and application combat. '
      'Lao Meng, focus on sharing Flutter technology and application combat. ',),

)

The background image size is 57x80:

The triangle on the right is no longer in the middle. If you want to keep it centered, modify the stretch area:

centerSlice:Rect.fromLTWH(20, 10, 1, 60),

Round framed avatar

Container(
  width:100,
  height:100,
  padding:EdgeInsets.all(3),
  decoration:BoxDecoration(shape:BoxShape.circle, color:Colors.blue),
  child:Container(
    decoration:BoxDecoration(
        shape:BoxShape.circle,
        image:DecorationImage(
            image:AssetImage('assets/images/aa.jpg'), fit:BoxFit.cover)),
 ),

)

Picture placeholder:

Image.network(
  'https://flutter.github.io/assets-for-api-docs/assets/widgets/puffin.jpg',
  height:150,
  width:150,
  fit:BoxFit.cover,
  frameBuilder:(
    BuildContext context,
    Widget child,
    int frame,
    bool wasSynchronouslyLoaded,
 ) {
    if(frame == null) {
      return Image.asset(
        'assets/images/place.png',
        height:150,
        width:150,
        fit:BoxFit.cover,
     );
    }
    return child;
  },

)

Add your own icon library

If the icon provided by the system does not have the icon we want, you need to introduce the icon of the third-party library. The following uses Alibaba's icon library as an example.

Open Alibaba's icon official website , after finding the icon you want, place the mouse on the icon and add it to the shopping cart:

Click the shopping cart in the upper right corner, then click Add to item:

If you have not added a project, you need to create a new project:

After creating, join this project, jump to the My Project page, and click to download:

Unzip the downloaded file. There are several unzipped files, as shown below:

Select the iconfont.ttf file and copy it to the assets/fonts directory of the Flutter project. The assets/fonts directory is not available by default and needs to be created manually. Set it in pubspec.yaml as follows:

Be sure to pay attention to the space at the beginning of the red box, otherwise the compilation will not pass, and the string following family is best meaningful. It needs to be used when the icon is used later.

The usage is as follows:

Icon(IconData(0xe613,fontFamily:'appIconFonts')

0xe613 has been marked when downloading the icon, replace &# with 0, as shown below:

fontFamily is the family property set in pubspec.yaml. The third-party icons are the same as the system icons, and their colors and sizes can be set.

communicate with

Old Meng Flutter blog address(330 control usage): http://laomengit.com

Welcome to join the Flutter communication group(WeChat:laomengit), follow the public number [Lao Meng Flutter]:

| | |