Kinda Code
Home/Flutter/How to save network images to the device in Flutter

How to save network images to the device in Flutter

Last updated: February 27, 2023

This article shows you how to save network images to the device’s storage when using a Flutter application.

To send HTTP requests and work with the device’s filesystem better, we need 3 plugins:

  • path_provider: Used to find commonly used locations on the filesystem.
  • path: Used to manipulate path (e.g. joining, splitting, normalizing),
  • http: Used to make HTTP requests

All of these ones are official plugins published by the Flutter and Dart team.

Install Plugins

1. Install http, path, and path_provider by executing the following command:

flutter pub add path path_provider http

2. Run the following command:

flutter pub get

3. Import the plugins into your Dart code:

import 'package:path_provider/path_provider.dart' as pathProvider;
import 'package:path/path.dart' as path;
import 'package:http/http.dart' as http;

Example

App Preview

We’ll make a tiny Flutter app that contains a button. When the user presses that button, the app starts downloading an image from the internet. After that process is done, the saved image will show up on the screen.

The Code

This is the function that will download the image from a given URL:

Future<void> _download(String url) async {
    final response = await http.get(Uri.parse(url));

    // Get the image name
    final imageName = path.basename(url);
    // Get the document directory path
    final appDir = await path_provider.getApplicationDocumentsDirectory();

    // This is the saved image path
    // You can use it to display the saved image later
    final localPath = path.join(appDir.path, imageName);

    // Downloading
    final imageFile = File(localPath);
    await imageFile.writeAsBytes(response.bodyBytes);
}

The full source code (with explanations):

// main.dart
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart' as path_provider;

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // This is the image file that will be displayed
  // In the beginning, it is null
  File? _displayImage;

  // This is the flag to check if the image is downloading
  // If it is true, the screen will show "Downloading..."
  bool _isDownloading = false;

  // URL of the image to download from the internet
  final String _url =
      'https://www.kindacode.com/wp-content/uploads/2022/02/orange.jpeg';

  Future<void> _download() async {
    // Set the flag to true
    setState(() {
      _isDownloading = true;
    });

    final response = await http.get(Uri.parse(_url));

    // Get the image name
    final imageName = path.basename(_url);
    // Get the document directory path
    final appDir = await path_provider.getApplicationDocumentsDirectory();

    // This is the saved image path
    // You can use it to display the saved image later
    final localPath = path.join(appDir.path, imageName);

    // Download the image
    final imageFile = File(localPath);
    await imageFile.writeAsBytes(response.bodyBytes);

    setState(() {
      _isDownloading = false;
      _displayImage = imageFile;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Kindacode.com'),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(25),
          child: Column(
            children: [
              ElevatedButton(
                  onPressed: _download, child: const Text('Download Image')),
              const SizedBox(height: 25),
              _displayImage != null
                  ? Image.file(_displayImage!)
                  : Center(
                      child: _isDownloading
                          ? const Text(
                              'Downloading...',
                              style: TextStyle(fontSize: 35),
                            )
                          : null,
                    )
            ],
          ),
        ),
      ),
    );
  }
}

Afterword

We’ve examined a small but meaningful example that demonstrates how to download network images to the local device. If you’d like to explore more new and fascinating stuff about Flutter and modern mobile development, take a look at the following articles:

You can also take a tour around our Flutter topic page and Dart topic page to see the latest tutorials and examples.