David Serrano
David Serrano

Follow

David Serrano

Follow
Save image to file in Flutter

Save image to file in Flutter

How to download an image file from an URL and save it to a directory

David Serrano's photo
David Serrano
·Feb 19, 2023·

3 min read

Saving an image downloaded from the Internet in the filesystem is one of the most elementary tasks that any application can do.

Convert image to file: what we'll learn

In this article, we will start from the base that we already have the URL of an image that we want to first download and then save in the gallery or to a given directory.

In addition, we will perform this action through the actions of the operating system, so it will not be necessary to declare sensitive permissions.

Save image from URL: how-to steps

Setup

Create a Flutter app for Android and iOS:

flutter create --platforms android,ios save_image_to_file

To do this task we will use the following dependencies:

  • flutter_file_dialog: We will use it to request the operating system to ask the user where they want to save the image and to perform said saving.

  • path_provider: We will need to find the directory of temporary files to create the first temporary copy of the file.

  • http: It will be necessary to download the image in the temporary directory.

Install the dependencies with the following command:

flutter pub add flutter_file_dialog path_provider http

Create a basic layout

Now we are going to create a very basic layout that displays an image:

Replace the contents of lib/main.dart with the following:

import 'package:flutter/material.dart';

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

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Save image to disk',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MainScreen(),
    );
  }
}

class MainScreen extends StatelessWidget {
  static const _url =
      'https://upload.wikimedia.org/wikipedia/en/8/86/Einstein_tongue.jpg';

  const MainScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Save image to disk'),
        actions: [
          IconButton(
            onPressed: () {
              // We will add this method later
            },
            icon: const Icon(Icons.save),
          ),
        ],
      ),
      body: Center(
        child: Container(
          padding: const EdgeInsets.only(
            left: 24.0,
            right: 24.0,
          ),
          child: ClipRRect(
            borderRadius: BorderRadius.circular(30.0),
            child: Image.network(_url),
          ),
        ),
      ),
    );
  }
}

Save the image from the URL to a file

The last step is to save the image to disk. This in turn consists of three actions:

  1. First, we will have to download the image in the memory of the application.

  2. We will then create an image file in a temporary location, where the app can write to it without asking for permission.

  3. Finally, we will invoke the system to make the final saving of the image in the location chosen by the user.

Add the following private function to MainScreen:

Future<void> _saveImage(BuildContext context) async {
  String? message;
  final scaffoldMessenger = ScaffoldMessenger.of(context);

  try {
    // Download image
    final http.Response response = await http.get(Uri.parse(_url));

    // Get temporary directory
    final dir = await getTemporaryDirectory();

    // Create an image name
    var filename = '${dir.path}/image.png';

    // Save to filesystem
    final file = File(filename);
    await file.writeAsBytes(response.bodyBytes);

    // Ask the user to save it
    final params = SaveFileDialogParams(sourceFilePath: file.path);
    final finalPath = await FlutterFileDialog.saveFile(params: params);

    if (finalPath != null) {
      message = 'Image saved to disk';
    }
  } catch (e) {
    message = 'An error occurred while saving the image';
  }

  if (message != null) {
    scaffoldMessenger.showSnackBar(SnackBar(content: Text(message)));
  }
}

You will need also to import the relevant libraries:

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_file_dialog/flutter_file_dialog.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';

Now we will simply have to call this method on the IconButton that we have previously added to the AppBar of our Scaffold:

// [...]
IconButton(
  // Call the method we just created
  onPressed: () => _saveImage(context),
  icon: const Icon(Icons.save),
),
// [...]

And that's it, run the app and you will see that you can download the image from the URL in the directory of your choice.

You can find the source code for this tutorial here.

Happy coding!

Did you find this article valuable?

Support David Serrano by becoming a sponsor. Any amount is appreciated!

See recent sponsors | Learn more about Hashnode Sponsors