Flutter Images

Flutter, Google's UI toolkit for building natively compiled applications, provides robust support for various image types and optimization techniques.

Adding Images to Your Flutter Project

To add images to your Flutter project, follow these steps:

  1. Create an images folder in your project root (or within the assets folder)
  2. Place your image files in this folder
  3. Update your pubspec.yaml file to include these assets:
flutter:  
 assets:  
 - assets/images/  
 # Or list individual files  
 - assets/images/logo.png  
 - assets/images/background.jpg  

After updating the pubspec.yaml file, run flutter pub get to update your project.

Displaying Images in Flutter

Flutter provides several widgets for displaying images:

1. Image Widget

The Image widget is the primary way to display images in Flutter. It offers various constructors:

// Display image from assets  
Image.asset('assets/images/logo.png')  
  
// Display image from network  
Image.network('https://example.com/image.jpg')  
  
// Display image from file  
Image.file(File('path o/file.png'))  
  
// Display image from memory  
Image.memory(bytes)  

2. Basic Example

Here's a simple example of displaying an asset image:

import 'package:flutter/material.dart';  
  
class ImageExample extends StatelessWidget {  
 @override  
 Widget build(BuildContext context) {  
 return Scaffold(  
 appBar: AppBar(  
 title: Text('Flutter Image Example'),  
 ),  
 body: Center(  
 child: Image.asset(  
 'assets/images/flutter_logo.png',  
 width: 200,  
 height: 200,  
 ),  
 ),  
 );  
 }  
}  

Image Widget Properties

The Image widget offers many properties to control how images are displayed:

Image.asset(  
 'assets/images/photo.jpg',  
 width: 300, // Set width  
 height: 200,  // Set height  
 fit: BoxFit.cover,  // How image should be inscribed into the space  
 alignment: Alignment.center, // Alignment within the box  
 color: Colors.blue, // Apply color overlay  
 colorBlendMode: BlendMode.lighten, // Blend mode for color  
 filterQuality: FilterQuality.high, // Quality of image filtering  
 isAntiAlias: true,  // Use anti-aliasing  
 repeat: ImageRepeat.noRepeat, // Repeat the image  
)  

BoxFit Options

The fit property controls how the image should be inscribed into its container:

  • BoxFit.fill: Stretch the image to fill the box
  • BoxFit.contain: Ensure the entire image fits within the box
  • BoxFit.cover: Fill the box, may crop the image
  • BoxFit.fitWidth: Match the width of the box
  • BoxFit.fitHeight: Match the height of the box
  • BoxFit.none: Align the image within the box without scaling
  • BoxFit.scaleDown: Scale down to fit if needed, but never scale up

Image Asset Variants

Flutter supports resolution-appropriate images for different device pixel ratios, similar to Android's drawable resource directories:

assets/  
 images/  
 my_image.png  // 1.0x (baseline)  
 1.5x/my_image.png // 1.5x resolution  
 2.0x/my_image.png // 2.0x resolution  
 3.0x/my_image.png // 3.0x resolution  
 4.0x/my_image.png // 4.0x resolution  

In your code, you reference only the base asset:

Image.asset('assets/images/my_image.png')  

Flutter automatically selects the appropriate asset based on the device's pixel ratio.

Network Images

Loading images from the internet is straightforward with Image.network:

Image.network(  
 'https://flutter.dev/images/flutter-logo-sharing.png',  
 loadingBuilder: (context, child, loadingProgress) {  
 if (loadingProgress == null) return child;  
 return Center(  
 child: CircularProgressIndicator(  
 value: loadingProgress.expectedTotalBytes != null  
 ? loadingProgress.cumulativeBytesLoaded /   
 loadingProgress.expectedTotalBytes!  
 : null,  
 ),  
 );  
 },  
 errorBuilder: (context, error, stackTrace) {  
 return Text('Failed to load image');  
 },  
)  

Don't forget to add internet permission to your Android manifest:

<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">  
 <uses-permission android:name=\"android.permission.INTERNET\" />  
 <!-- Other content -->  
</manifest>  

Caching Images

For efficient network image caching, use the cached_network_image package:

  1. Add the dependency to pubspec.yaml:
dependencies:  
 cached_network_image: ^3.3.0  
  1. Use it in your code:
import 'package:cached_network_image/cached_network_image.dart';  
  
CachedNetworkImage(  
 imageUrl: 'https://example.com/image.jpg',  
 placeholder: (context, url) => CircularProgressIndicator(),  
 errorWidget: (context, url, error) => Icon(Icons.error),  
)  

Image Loading and Placeholders

Creating a good user experience involves handling loading states properly:

// Using FadeInImage for smooth loading transition  
FadeInImage.assetNetwork(  
 placeholder: 'assets/images/loading.gif',  
 image: 'https://example.com/image.jpg',  
 fadeInDuration: Duration(milliseconds: 700),  
 fadeOutDuration: Duration(milliseconds: 300),  
)  
  
// Or with memory placeholder  
FadeInImage.memoryNetwork(  
 placeholder: kTransparentImage, // from 'package:transparent_image'  
 image: 'https://example.com/image.jpg',  
)  

Advanced Image Techniques

1. SVG Images

To use SVG images, add the flutter_svg package:

dependencies:  
 flutter_svg: ^2.0.8  

Then use it in your code:

import 'package:flutter_svg/flutter_svg.dart';  
  
SvgPicture.asset(  
 'assets/images/icon.svg',  
 width: 100,  
 height: 100,  
)  

2. Image Filtering and Effects

Apply filters and effects to images:

ColorFiltered(  
 colorFilter: ColorFilter.mode(  
 Colors.red,  
 BlendMode.modulate,  
 ),  
 child: Image.asset('assets/images/photo.jpg'),  
)  
  
// Or use ImageFiltered widget for more effects  
ImageFiltered(  
 imageFilter: ImageFilter.blur(  
 sigmaX: 5.0,  
 sigmaY: 5.0,  
 ),  
 child: Image.asset('assets/images/photo.jpg'),  
)  

3. Custom Image Loading

Create a custom image loading widget:

class CustomImage extends StatelessWidget {  
 final String url;  
 final double width;  
 final double height;  
  
 const CustomImage({  
 required this.url,  
 this.width = 100,  
 this.height = 100,  
 });  
  
 @override  
 Widget build(BuildContext context) {  
 return CachedNetworkImage(  
 imageUrl: url,  
 width: width,  
 height: height,  
 fit: BoxFit.cover,  
 placeholder: (context, url) => Container(  
 color: Colors.grey[300],  
 child: Center(  
 child: CircularProgressIndicator(),  
 ),  
 ),  
 errorWidget: (context, url, error) => Container(  
 color: Colors.grey[300],  
 child: Center(  
 child: Icon(Icons.error),  
 ),  
 ),  
 );  
 }  
}  

Related Topics