Flutter图片保存插件gallery_saver_plus的使用

Flutter图片保存插件 gallery_saver_plus 的使用

gallery_saver_plus 是一个用于在Flutter应用中保存图片和视频到外部存储(如Android的相册或iOS的照片库)的插件。本文将详细介绍如何安装和使用该插件,并提供完整的示例代码。

安装

首先,在您的 pubspec.yaml 文件中添加 gallery_saver_plus 作为依赖项:

dependencies:
  gallery_saver_plus: ^latest_version

iOS 配置

<project root>/ios/Runner/Info.plist 文件中添加以下键值对:

<key>NSPhotoLibraryUsageDescription</key>
<string>我们需要访问您的照片库以保存图片和视频。</string>

Android 配置

AndroidManifest.xml 文件中添加以下权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

使用示例

下面是一个完整的示例,展示了如何使用 gallery_saver_plus 插件来保存从相机拍摄的照片和视频,以及从网络链接保存图片和视频。

示例代码

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:gallery_saver_plus/gallery_saver.dart';
import 'package:image_picker/image_picker.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String firstButtonText = '拍照';
  String secondButtonText = '录制视频';
  double textSize = 20;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Container(
          color: Colors.white,
          child: Column(
            children: <Widget>[
              Flexible(
                flex: 1,
                child: Container(
                  child: SizedBox.expand(
                    child: RaisedButton(
                      color: Colors.blue,
                      onPressed: _takePhoto,
                      child: Text(firstButtonText,
                          style: TextStyle(fontSize: textSize, color: Colors.white)),
                    ),
                  ),
                ),
              ),
              Flexible(
                child: Container(
                  child: SizedBox.expand(
                    child: RaisedButton(
                      color: Colors.white,
                      onPressed: _recordVideo,
                      child: Text(secondButtonText,
                          style: TextStyle(fontSize: textSize, color: Colors.blueGrey)),
                    ),
                  ),
                ),
                flex: 1,
              ),
              Flexible(
                child: Container(
                  child: SizedBox.expand(
                    child: RaisedButton(
                      color: Colors.green,
                      onPressed: _saveNetworkImage,
                      child: Text('保存网络图片',
                          style: TextStyle(fontSize: textSize, color: Colors.white)),
                    ),
                  ),
                ),
                flex: 1,
              ),
              Flexible(
                child: Container(
                  child: SizedBox.expand(
                    child: RaisedButton(
                      color: Colors.red,
                      onPressed: _saveNetworkVideo,
                      child: Text('保存网络视频',
                          style: TextStyle(fontSize: textSize, color: Colors.white)),
                    ),
                  ),
                ),
                flex: 1,
              ),
            ],
          ),
        ),
      ),
    );
  }

  void _takePhoto() async {
    final pickedFile = await ImagePicker().pickImage(source: ImageSource.camera);
    if (pickedFile != null) {
      setState(() {
        firstButtonText = '保存中...';
      });
      GallerySaver.saveImage(pickedFile.path).then((String path) {
        setState(() {
          firstButtonText = '图片已保存!';
        });
      });
    }
  }

  void _recordVideo() async {
    final pickedFile = await ImagePicker().pickVideo(source: ImageSource.camera);
    if (pickedFile != null) {
      setState(() {
        secondButtonText = '保存中...';
      });
      GallerySaver.saveVideo(pickedFile.path).then((String path) {
        setState(() {
          secondButtonText = '视频已保存!';
        });
      });
    }
  }

  void _saveNetworkImage() async {
    String imageUrl =
        'https://image.shutterstock.com/image-photo/montreal-canada-july-11-2019-600w-1450023539.jpg';
    GallerySaver.saveImage(imageUrl).then((bool success) {
      setState(() {
        print('图片已保存');
      });
    });
  }

  void _saveNetworkVideo() async {
    String videoUrl =
        'https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4';
    GallerySaver.saveVideo(videoUrl).then((bool success) {
      setState(() {
        print('视频已保存');
      });
    });
  }
}

解释

  1. 拍照功能:点击“拍照”按钮后,调用 ImagePicker().pickImage 方法打开相机并获取图片路径。然后使用 GallerySaver.saveImage 将图片保存到相册。

  2. 录制视频功能:点击“录制视频”按钮后,调用 ImagePicker().pickVideo 方法打开相机录制视频并获取视频路径。然后使用 GallerySaver.saveVideo 将视频保存到相册。

  3. 保存网络图片:点击“保存网络图片”按钮后,调用 GallerySaver.saveImage 方法将指定的网络图片URL保存到相册。

  4. 保存网络视频:点击“保存网络视频”按钮后,调用 GallerySaver.saveVideo 方法将指定的网络视频URL保存到相册。

注意事项

  • 网络图片或视频的链接必须包含 http/https 前缀。
  • 在实际应用中,您可能需要处理更多的错误情况和用户权限请求。

通过以上步骤,您可以轻松地在Flutter应用中实现图片和视频的保存功能。


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

1 回复

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


当然,下面是一个关于如何使用 gallery_saver_plus 插件在 Flutter 应用中保存图片的示例代码。gallery_saver_plus 是一个用于将图片保存到设备图库的 Flutter 插件。

步骤 1: 添加依赖

首先,在你的 pubspec.yaml 文件中添加 gallery_saver_plus 依赖:

dependencies:
  flutter:
    sdk: flutter
  gallery_saver_plus: ^3.0.2  # 请检查最新版本号

然后运行 flutter pub get 来获取依赖。

步骤 2: 配置权限

在 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 文件中添加相应的权限描述(尽管从 iOS 14 开始,照片库的访问权限通常通过运行时请求处理):

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

步骤 3: 请求权限(可选,但推荐)

在实际保存图片之前,最好检查并请求必要的权限。可以使用 permission_handler 插件来管理权限请求。

pubspec.yaml 中添加 permission_handler 依赖:

dependencies:
  permission_handler: ^10.2.0  # 请检查最新版本号

然后运行 flutter pub get

步骤 4: 保存图片

下面是一个完整的示例,展示如何请求权限并保存图片到图库:

import 'package:flutter/material.dart';
import 'package:gallery_saver_plus/gallery_saver_plus.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> {
  Future<void> _saveImageToGallery() async {
    // 请求存储权限
    var status = await Permission.storage.status;
    if (!status.isGranted) {
      var result = await Permission.storage.request();
      if (!result.isGranted) {
        return; // 用户拒绝了权限请求
      }
    }

    // 生成一个简单的图片(这里使用 Flutter 的 Canvas 绘制一个红色矩形作为示例)
    final ByteData? imageBytes = await _capturePng();
    if (imageBytes == null) {
      return;
    }

    // 保存图片到图库
    final bool result = await GallerySaver.saveImage(
      imageBytes.buffer.asUint8List(),
      quality: 100,
      name: 'example_image',
    );

    if (result) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Image saved to gallery')),
      );
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Failed to save image')),
      );
    }
  }

  Future<ByteData?> _capturePng() async {
    try {
      RenderRepaintBoundary boundary =
          globalKey.currentContext!.findRenderObject()! as RenderRepaintBoundary;
      ui.Image image = await boundary.toImage();
      ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
      return byteData;
    } catch (e) {
      print(e);
      return null;
    }
  }

  final GlobalKey globalKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Save Image to Gallery'),
      ),
      body: Center(
        child: RepaintBoundary(
          key: globalKey,
          child: Container(
            width: 200,
            height: 200,
            color: Colors.red,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _saveImageToGallery,
        tooltip: 'Save Image',
        child: Icon(Icons.save),
      ),
    );
  }
}

在这个示例中,我们使用 RepaintBoundary 捕获一个简单的红色矩形图片,并使用 gallery_saver_plus 将其保存到设备图库。注意,这个示例假设用户已经授予了存储权限;在实际应用中,你应该处理权限请求的结果,并适当地提示用户。

回到顶部