Flutter图片保存到相册插件image_gallery_saver的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter图片保存到相册插件image_gallery_saver的使用

image_gallery_saver

Build Status pub package license

image_gallery_saver 插件用于将图片保存到设备的相册中,当您需要保存从网络获取或本地生成的图片时,这个插件非常有用。

使用方法

添加依赖

在您的 pubspec.yaml 文件中添加 image_gallery_saver 作为依赖项:

dependencies:
  image_gallery_saver: '^2.0.3'

iOS配置

在iOS上,您需要创建一个基于Swift的项目,并且需要在 Info.plist 文件中添加以下键值对来请求照片库写入权限:

  • NSPhotoLibraryAddUsageDescription - 解释为什么您的应用程序需要照片库写入权限。在Xcode的可视化编辑器中,这个键被命名为“Privacy - Photo Library Additions Usage Description”。

Android配置

对于Android,您需要请求存储权限以保存图片到相册。可以使用 flutter_permission_handler 来处理权限请求。此外,在Android 10及以上版本中,您还需要在 AndroidManifest.xml 文件的应用程序标签内添加如下属性:

<application android:requestLegacyExternalStorage="true" .....>

示例代码

下面是一个完整的示例demo,展示了如何使用 image_gallery_saver 插件保存不同类型的文件(如图片、GIF和视频)到相册中。

import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path_provider/path_provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Save image to gallery',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  GlobalKey _globalKey = GlobalKey();

  @override
  void initState() {
    super.initState();
    // PermissionUtil.requestAll(); // 如果您使用了权限管理工具,确保在这里请求所有必要的权限。
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Save image to gallery"),
        ),
        body: Center(
          child: Column(
            children: <Widget>[
              SizedBox(height: 15),
              RepaintBoundary(
                key: _globalKey,
                child: Container(
                  alignment: Alignment.center,
                  width: 300,
                  height: 300,
                  color: Colors.blue,
                ),
              ),
              ElevatedButton(
                onPressed: _saveLocalImage,
                child: Text("Save Local Image"),
              ),
              SizedBox(height: 15),
              ElevatedButton(
                onPressed: _saveNetworkImage,
                child: Text("Save Network Image"),
              ),
              SizedBox(height: 15),
              ElevatedButton(
                onPressed: _saveNetworkGifFile,
                child: Text("Save Network Gif Image"),
              ),
              SizedBox(height: 15),
              ElevatedButton(
                onPressed: _saveNetworkVideoFile,
                child: Text("Save Network Video"),
              ),
            ],
          ),
        ));
  }

  _saveLocalImage() async {
    RenderRepaintBoundary boundary =
        _globalKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
    ui.Image image = await boundary.toImage();
    ByteData? byteData =
        await (image.toByteData(format: ui.ImageByteFormat.png));
    if (byteData != null) {
      final result =
          await ImageGallerySaver.saveImage(byteData.buffer.asUint8List());
      print(result);
      // Utils.toast(result.toString()); // 如果有自定义工具类的话可以这样调用
    }
  }

  _saveNetworkImage() async {
    var response = await Dio().get(
        "https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=a62e824376d98d1069d40a31113eb807/838ba61ea8d3fd1fc9c7b6853a4e251f94ca5f46.jpg",
        options: Options(responseType: ResponseType.bytes));
    final result = await ImageGallerySaver.saveImage(
        Uint8List.fromList(response.data),
        quality: 60,
        name: "hello");
    print(result);
    // Utils.toast("$result"); // 如果有自定义工具类的话可以这样调用
  }

  _saveNetworkGifFile() async {
    var appDocDir = await getTemporaryDirectory();
    String savePath = appDocDir.path + "/temp.gif";
    String fileUrl =
        "https://hyjdoc.oss-cn-beijing.aliyuncs.com/hyj-doc-flutter-demo-run.gif";
    await Dio().download(fileUrl, savePath);
    final result =
        await ImageGallerySaver.saveFile(savePath, isReturnPathOfIOS: true);
    print(result);
    // Utils.toast("$result"); // 如果有自定义工具类的话可以这样调用
  }

  _saveNetworkVideoFile() async {
    var appDocDir = await getTemporaryDirectory();
    String savePath = appDocDir.path + "/temp.mp4";
    String fileUrl =
        "https://s3.cn-north-1.amazonaws.com.cn/mtab.kezaihui.com/video/ForBiggerBlazes.mp4";
    await Dio().download(fileUrl, savePath, onReceiveProgress: (count, total) {
      print((count / total * 100).toStringAsFixed(0) + "%");
    });
    final result = await ImageGallerySaver.saveFile(savePath);
    print(result);
    // Utils.toast("$result"); // 如果有自定义工具类的话可以这样调用
  }
}

此示例包含了四个按钮,分别用于保存本地绘制的图片、网络上的图片、GIF动画以及视频到相册中。您可以根据自己的需求选择合适的功能进行测试。注意,实际应用中可能还需要处理权限请求等细节问题。


更多关于Flutter图片保存到相册插件image_gallery_saver的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter图片保存到相册插件image_gallery_saver的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用image_gallery_saver插件将图片保存到相册的详细代码示例。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加image_gallery_saver依赖:

dependencies:
  flutter:
    sdk: flutter
  image_gallery_saver: ^2.1.0  # 请检查最新版本号

然后运行flutter pub get来安装依赖。

2. 请求权限

在Android和iOS上保存图片到相册需要请求存储权限。以下是如何在Flutter中请求这些权限的示例代码。

Android权限请求

android/app/src/main/AndroidManifest.xml文件中添加权限:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    
    <!-- 其他配置 -->

</manifest>

iOS权限请求

ios/Runner/Info.plist文件中添加权限:

<key>NSPhotoLibraryAddUsageDescription</key>
<string>App needs access to save photos</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>App needs access to photo library</string>

3. 请求权限并保存图片

在你的Dart代码中,使用permission_handler插件来请求权限,然后使用image_gallery_saver保存图片。首先,添加permission_handler依赖:

dependencies:
  flutter:
    sdk: flutter
  image_gallery_saver: ^2.1.0
  permission_handler: ^8.1.4  # 请检查最新版本号

然后,你可以使用以下代码来请求权限并保存图片:

import 'package:flutter/material.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:permission_handler/permission_handler.dart';
import 'dart:typed_data';
import 'dart:ui' as ui;

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SaveImageScreen(),
    );
  }
}

class SaveImageScreen extends StatefulWidget {
  @override
  _SaveImageScreenState createState() => _SaveImageScreenState();
}

class _SaveImageScreenState extends State<SaveImageScreen> {
  Uint8List? imageBytes;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Save Image to Gallery'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () async {
                // 生成一个示例图片(红色方块)
                final recorder = ui.PictureRecorder();
                final canvas = Canvas(recorder);
                final paint = Paint()
                  ..color = Colors.red
                  ..style = PaintingStyle.fill;
                canvas.drawRect(Rect.fromLTWH(0, 0, 200, 200), paint);
                final picture = recorder.endRecording();
                final image = await picture.toImage(200, 200);
                final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
                imageBytes = byteData!.buffer.asUint8List();

                // 请求存储权限
                var status = await Permission.storage.status;
                if (!status.isGranted) {
                  status = await Permission.storage.request();
                  if (!status.isGranted) {
                    return;
                  }
                }

                // 保存图片到相册
                bool result = await ImageGallerySaver.saveImage(imageBytes!);
                if (result) {
                  ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                    content: Text('Image saved successfully!'),
                  ));
                } else {
                  ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                    content: Text('Failed to save image.'),
                  ));
                }
              },
              child: Text('Generate and Save Image'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们首先生成一个简单的红色方块图片,然后请求存储权限,如果权限被授予,则将图片保存到相册。

希望这个示例对你有帮助!如果你有任何其他问题,请随时提问。

回到顶部