Flutter本地存储与媒体文件(图片视频)选择插件local_storage_image_video_picker的使用

Flutter本地存储与媒体文件(图片视频)选择插件local_storage_image_video_picker的使用

在Flutter开发中,处理本地存储和媒体文件的选择是一个常见的需求。本文将介绍如何使用local_storage_image_video_picker插件来实现这一功能。该插件允许用户从设备中选择图片和视频,并支持保存网络图片到本地。

插件安装

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

dependencies:
  local_storage_image_video_picker: ^版本号

然后运行以下命令以获取依赖:

flutter pub get

使用示例

以下是完整的示例代码,展示了如何使用local_storage_image_video_picker插件来选择图片和视频,并保存到本地。

示例代码

import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:local_storage_image_video_picker/local_storage_image_video_picker.dart';
import 'dart:ui' as ui;

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

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  GalleryMode _galleryMode = GalleryMode.image;
  GlobalKey? globalKey;
  [@override](/user/override)
  void initState() {
    super.initState();
    globalKey = GlobalKey();
  }

  List<Media> _listImagePaths = [];
  List<Media> _listVideoPaths = [];
  String? dataImagePath = "";

  Future<void> selectImages() async {
    try {
      _galleryMode = GalleryMode.image;
      _listImagePaths = await ImagePickers.pickerPaths(
          galleryMode: _galleryMode,
          showGif: true,
          selectCount: 9,
          showCamera: true,
          cropConfig: CropConfig(enableCrop: true, height: 1, width: 1),
          compressSize: 500,
          uiConfig: UIConfig(uiThemeColor: Color(0xffff0000),),
      );
      print(_listImagePaths.length);
      if (_listImagePaths.length > 0) {
        _listImagePaths.forEach((media) {
          print(media.path.toString());
        });
      }
      setState(() {});
    } on PlatformException {}
  }

  Future<void> selectVideos() async {
    try {
      _galleryMode = GalleryMode.video;
      _listVideoPaths = await ImagePickers.pickerPaths(
        galleryMode: _galleryMode,
        selectCount: 2,
        showCamera: true,
      );
      setState(() {});
      print(_listVideoPaths);
    } on PlatformException {}
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return RepaintBoundary(
      key: globalKey,
      child: MaterialApp(
        theme: ThemeData(
          backgroundColor: Colors.white,
          primaryColor: Colors.white,
        ),
        home: Scaffold(
          appBar: AppBar(
            title: const Text('多图选择'),
          ),
          body: SingleChildScrollView(
            physics: BouncingScrollPhysics(),
            child: Column(
              children: <Widget>[
                GridView.builder(
                    physics: NeverScrollableScrollPhysics(),
                    itemCount: _listImagePaths.length,
                    shrinkWrap: true,
                    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: 3,
                        mainAxisSpacing: 20.0,
                        crossAxisSpacing: 10.0,
                        childAspectRatio: 1.0),
                    itemBuilder: (BuildContext context, int index) {
                      return GestureDetector(
                        onTap: () {
                          ImagePickers.previewImagesByMedia(_listImagePaths, index);
                        },
                        child: Image.file(
                          File(
                            _listImagePaths[index].path!,
                          ),
                          fit: BoxFit.cover,
                        ),
                      );
                    }),
                ElevatedButton(
                  onPressed: () {
                    selectImages();
                  },
                  child: Text("选择图片"),
                ),
                ElevatedButton(
                  onPressed: () async {
                    ImagePickers.openCamera(cropConfig: CropConfig(enableCrop: true, width: 2, height: 3)).then((Media? media) {
                      _listImagePaths.clear();
                      if (media != null) {
                        _listImagePaths.add(media);
                      }
                      setState(() {});
                    });
                  },
                  child: Text("拍照"),
                ),
                ElevatedButton(
                  onPressed: () {
                    ImagePickers.openCamera(cameraMimeType: CameraMimeType.video).then((Media? media) {
                      _listVideoPaths.clear();
                      if (media != null) {
                        print(media.path);
                        _listVideoPaths.add(media);
                      }
                      setState(() {});
                    });
                  },
                  child: Text("拍视频"),
                ),
                GridView.builder(
                    physics: NeverScrollableScrollPhysics(),
                    itemCount: _listVideoPaths.length,
                    shrinkWrap: true,
                    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: 3,
                        mainAxisSpacing: 20.0,
                        crossAxisSpacing: 10.0,
                        childAspectRatio: 1.0),
                    itemBuilder: (BuildContext context, int index) {
                      return GestureDetector(
                        onTap: () {
                          ImagePickers.previewVideo(_listVideoPaths[index].path!);
                        },
                        child: Image.file(
                          File(
                            _listVideoPaths[index].thumbPath!,
                          ),
                          fit: BoxFit.cover,
                        ),
                      );
                    }),
                ElevatedButton(
                  onPressed: () {
                    selectVideos();
                  },
                  child: Text("选择视频"),
                ),

                InkWell(
                  onTap: () {
                    ImagePickers.previewImage("http://i1.sinaimg.cn/ent/d/2008-06-04/U105P28T3D2048907F326DT20080604225106.jpg");
                  },
                  child: Image.network("http://i1.sinaimg.cn/ent/d/2008-06-04/U105P28T3D2048907F326DT20080604225106.jpg", fit: BoxFit.cover, width: 100, height: 100,),
                ),
                ElevatedButton(
                  onPressed: () {
                    Future<String?> future = ImagePickers.saveImageToGallery("http://i1.sinaimg.cn/ent/d/2008-06-04/U105P28T3D2048907F326DT20080604225106.jpg");
                    future.then((path) {
                      print("保存图片路径:" + path!);
                    });
                  },
                  child: Text("保存网络图片"),
                ),
                dataImagePath == "" ? Container() : GestureDetector(
                  onTap: () {
                    ImagePickers.previewImage(dataImagePath!);
                  },
                  child: Image.file(File(dataImagePath!), fit: BoxFit.cover, width: 100, height: 100,),
                ),
                ElevatedButton(
                  onPressed: () async {
                    RenderRepaintBoundary boundary = globalKey!.currentContext!.findRenderObject() as RenderRepaintBoundary;
                    ui.Image image = await boundary.toImage(pixelRatio: 3);
                    ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png) as ByteData;
                    Uint8List data = byteData.buffer.asUint8List();

                    dataImagePath = await ImagePickers.saveByteDataImageToGallery(data);

                    print("保存截屏图片 = " + dataImagePath!);
                    setState(() {});
                  },
                  child: Text("保存截屏图片"),
                ),

                ElevatedButton(
                  onPressed: () {
                    Future<String?> future = ImagePickers.saveVideoToGallery("http://vd4.bdstatic.com/mda-jbmn50510sid5yx5/sc/mda-jbmn50510sid5yx5.mp4");
                    future.then((path) {
                      print("视频保存成功" + path!);
                    });
                  },
                  child: Text("保存视频"),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

更多关于Flutter本地存储与媒体文件(图片视频)选择插件local_storage_image_video_picker的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter本地存储与媒体文件(图片视频)选择插件local_storage_image_video_picker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,如果你需要选择本地存储中的图片和视频,并对其进行处理,你可以使用一些现成的插件来实现这些功能。虽然目前没有一个名为 local_storage_image_video_picker 的官方插件,但你可以结合使用 image_pickervideo_player 等插件来实现类似的功能。

以下是如何使用这些插件来选择和处理本地存储中的图片和视频的步骤:

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  image_picker: ^0.8.5+3
  video_player: ^2.4.0

2. 使用 image_picker 选择图片和视频

image_picker 插件允许你从设备的相册或相机中选择图片和视频。

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:video_player/video_player.dart';

class ImageVideoPickerScreen extends StatefulWidget {
  @override
  _ImageVideoPickerScreenState createState() => _ImageVideoPickerScreenState();
}

class _ImageVideoPickerScreenState extends State<ImageVideoPickerScreen> {
  XFile? _imageFile;
  XFile? _videoFile;
  VideoPlayerController? _videoController;

  Future<void> _pickImage() async {
    final pickedFile = await ImagePicker().pickImage(source: ImageSource.gallery);

    setState(() {
      _imageFile = pickedFile;
    });
  }

  Future<void> _pickVideo() async {
    final pickedFile = await ImagePicker().pickVideo(source: ImageSource.gallery);

    setState(() {
      _videoFile = pickedFile;
      _videoController = VideoPlayerController.file(File(pickedFile!.path))
        ..initialize().then((_) {
          setState(() {});
          _videoController?.play();
        });
    });
  }

  @override
  void dispose() {
    _videoController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image & Video Picker'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _imageFile != null
                ? Image.file(File(_imageFile!.path))
                : Text('No image selected.'),
            _videoFile != null
                ? AspectRatio(
                    aspectRatio: _videoController!.value.aspectRatio,
                    child: VideoPlayer(_videoController!),
                  )
                : Text('No video selected.'),
            ElevatedButton(
              onPressed: _pickImage,
              child: Text('Pick Image'),
            ),
            ElevatedButton(
              onPressed: _pickVideo,
              child: Text('Pick Video'),
            ),
          ],
        ),
      ),
    );
  }
}

3. 处理选择的图片和视频

在上面的代码中,我们使用了 ImagePicker 来选择图片和视频。选择图片后,我们使用 Image.file 来显示图片。选择视频后,我们使用 VideoPlayerController 来播放视频。

4. 权限配置

在 Android 和 iOS 上,你需要确保应用有访问相机和存储的权限。

Android

AndroidManifest.xml 中添加以下权限:

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

iOS

Info.plist 中添加以下权限:

<key>NSCameraUsageDescription</key>
<string>We need access to your camera to take photos.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to your photo library to select photos.</string>
<key>NSMicrophoneUsageDescription</key>
<string>We need access to your microphone to record video.</string>
回到顶部