Flutter 中下载并保存图片为文件

原文链接:download and save image to file in Flutter - 原文作者 saurabhsinghaswal
本文采用意译的方式

任何应用程序都可以执行的最简单的活动之一是将互联网图片下载到文件系统中。

我们将学习怎么保存图片到本地的设备中,比如手机。开始之前,我们假设我们知道图片的 URL,我们会先下载图像,然后将其保存在相册或者指定的位置。

我们将使用下面的依赖:

步骤一:创建基本布局

我们创建一个很简单的布局,用来展示来自 URL 的图片:

相关代码如下:

dart 复制代码
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://dosomthings.com/wp-content/uploads/2022/07/dc0a7e44e96647848177c8afd4bdabdd.png';
  
  const MainScreen({super.key});
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Save image to disk'),
        centerTitle: true,
        backgroundColor: Color(0xFFe91e63),
        actions: [
          IconButton(
            onPressed: () {
              // 后面我们会在这里添加方法
            },
            icon: const Icon(Icons.save, color: Colors.white,),
          ),
        ],
      ),
      body: Center(
        child: Container(
          padding: const EdgeInsets.only(
            left: 24.0,
            right: 24.0,
          ),
          child: ClipRect(
            borderRadius: BorderRadius.circular(30.0),
            child: Image.network(_url),
          ),
        ),
      ),
    );
  }
}

步骤二:授权并在安卓中设定下载和保存图片的配置

bash 复制代码
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
package="com.example.saveimage">  
  <uses-permission android:name="android.permission.INTERNET"/>  
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />  
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
  <application>

然后,我们更新 compileSdkVersionminSdkVersion 版本:

bash 复制代码
android {  
  // 更改这里...  
  compileSdkVersion 33  
  
  ndkVersion flutter.ndkVersion  
  
  compileOptions {  
    sourceCompatibility JavaVersion.VERSION_1_8  
    targetCompatibility JavaVersion.VERSION_1_8  
  }
bash 复制代码
defaultConfig {  
  // TODO: 指定你自己独一无二的应用 ID (https://developer.android.com/studio/build/application-id.html).  
  applicationId "com.example.saveimage"  
  
  // 更改这里
  minSdkVersion 19  
  
  targetSdkVersion flutter.targetSdkVersion  
  versionCode flutterVersionCode.toInteger()  
  versionName flutterVersionName  
}

步骤三:从 URL 中下载并保存图像到文件

相关代码如下:

dart 复制代码
import 'dart:math';
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:flutter_file_dialog/flutter_file_dialog.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.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',
      home: MainScreen(),
    );
  }
}

class MainScreen extends StatelessWidget {
  static const _url = 'https://dosomthings.com/wp-content/uploads/2023/07/How-to-download-and-save-image-to-file-in-FlutterDosomthings.com_-1024x576.png';
  var random = Random();
  
  Future<void> _saveImage(BuildContext context) async {
    final ScaffoldMessenger = ScaffoldMessager.of(context);
    late String message;
    
    try {
      // 下载图片
      final http.Response response = await http.get(Uri.parse(_url));
      
      // 获取临时的文件夹
      final dir = await getTemporaryDirectory();
      
      // 创建一个图像名称
      var filename = '${dir.path}/SaveImage${random.nextInt(100)}.png';
      
      // 保存到文件系统
      final file = File(filename);
      await file.writeAsBytes(response.bodyBytes);
      
      // 询问用户是否保存它
      final params = SaveFileDialogParams(sourceFilePath: file.path);
      final finalPath = await FlutterFileDialog.saveFile(params: params);
      
      if(filePath != null) {
        message = 'Image saved to disk'
      }
    } catch (e) {
      message = e.toString();
      scaffoldMessager.showSnackBar(SnackBar(
        content: Text(
          message,
          style: TextStyle(
            fontSize: 12,
            color: Colors.white,
            fontWeight: FontWeight.bold
          ),
        ),
        backgroundColor: Color(0xFFe91e63),
      ));
    }
    if(message != null) {
      scaffoldMessenger.showSnackBar(SnackBar(
        content: Text(
          message,
          style: TextStyle(
            fontSize: 12,
            color: Colors.white,
            fontWeight: FontWeight.bold,
          ),
        ),
        backroundColor: Color(0xFFe91e63),
      ));
    }
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Save image to disk'),
        centerTitle: true,
        backgroundColor: Color(0xFFe91e63),
        actions: [
          IconButton(
            onPressed: () {
              _saveImage(context);
            },
            icon: const Icon(Icons.save, color: COlors.white,),
          ),
        ],
      ),
      body: Center(
        child: Container(
          padding: const EdgetInsets.only(
            left: 24.0,
            right: 24.0,
          ),
          child: ClipRect(
            borderRadius: BorderRadius.circular(30.0),
            child: Image.network(_url),
          ),
        ),
      ),
    );
  }
}

输出

效果截图如下:

effect_01 effect_02 effect_03

总结

在这篇文章中,我们已经学习了怎么用 Flutter 下载并保存图片到文件中。通过根据上面的步骤,我们可以整合图片下载和保存的功能到 Flutter 应用程序中,这将为离线查看图像和用户驱动的图像保存功能提供了可能性。

希望读者已经理解怎么下载图像。准确说,我也是在查阅了很多 youtube 频道和文章,但是没人能简洁地描述怎么去做下载图像文件这件事情,但是现在我做到了。现在,到你们来尝试了。

相关推荐
影子落人间3 分钟前
已解决npm ERR! request to https://registry.npm.taobao.org/@vant%2farea-data failed
前端·npm·node.js
世俗ˊ28 分钟前
CSS入门笔记
前端·css·笔记
子非鱼92128 分钟前
【前端】ES6:Set与Map
前端·javascript·es6
6230_32 分钟前
git使用“保姆级”教程1——简介及配置项设置
前端·git·学习·html·web3·学习方法·改行学it
想退休的搬砖人41 分钟前
vue选项式写法项目案例(购物车)
前端·javascript·vue.js
加勒比海涛1 小时前
HTML 揭秘:HTML 编码快速入门
前端·html
啥子花道1 小时前
Vue3.4 中 v-model 双向数据绑定新玩法详解
前端·javascript·vue.js
麒麟而非淇淋1 小时前
AJAX 入门 day3
前端·javascript·ajax
茶茶只知道学习1 小时前
通过鼠标移动来调整两个盒子的宽度(响应式)
前端·javascript·css
清汤饺子1 小时前
实践指南之网页转PDF
前端·javascript·react.js