flutter - 从Flutter中的图库中保存ImagePicker图像

标签 flutter dart

与往常一样,这些最简单的解决方案对我来说是最难解决的。我有ImagePicker函数可以从图库中获取图像并将其设置为背景。下面的代码可以正常工作,但是图像不会保存,因此每次重新启动后,图像都不会存在。这是代码:

Future _getImage() async {
final picker = ImagePicker();

final pickedFile = await picker.getImage(source: ImageSource.gallery);

setState(() {
  if (pickedFile != null) {
    _image = File(pickedFile.path);

    print('_image: $_image');
  } else {
    print('No image selected');
  }
});
}
因此,我的问题是如何保存图像以使其永久保存并在重新启动后继续存在,我已经尝试了所有方法(设置和保存路径等),由于某种原因使图像无法正常工作。希望解决方案很简单。我的理解是,应将其保存到设备的本地存储(在这种情况下为仿真器),但是它当然应该在所有设备上都可以使用。

最佳答案

您可以将用户从图库中挑选的图像保存到应用程序目录中。然后,使用此图像从本地存储中显示。

  • 使用path_provider获取目录路径
    Directory appDocDir = await getApplicationDocumentsDirectory();
    String appDocPath = appDocDir.path;
    
  • 将图像保存到目录
    final picker = ImagePicker();
    
    final pickedFile = await picker.getImage(source: ImageSource.gallery);
    
    if (pickedFile == null) return;
    
    _image = File(pickedFile.path);
    
    final fileName = 'background_image';
    final File localImage = await _image.copy('${widget.appDocPath}/$fileName');
    
  • 在小部件树中使用图像
    Image image;
    var hasLocalImage =
        File('${widget.appDocPath}/background_image').existsSync();
    if (hasLocalImage) {
      var bytes =
          File('${widget.appDocPath}/background_image').readAsBytesSync();
      image = Image.memory(bytes);
    }
    

  • 完整的工作示例:
    import 'dart:io';
    
    import 'package:flutter/material.dart';
    import 'package:image_picker/image_picker.dart';
    import 'package:path_provider/path_provider.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            // This is the theme of your application.
            //
            // Try running your application with "flutter run". You'll see the
            // application has a blue toolbar. Then, without quitting the app, try
            // changing the primarySwatch below to Colors.green and then invoke
            // "hot reload" (press "r" in the console where you ran "flutter run",
            // or simply save your changes to "hot reload" in a Flutter IDE).
            // Notice that the counter didn't reset back to zero; the application
            // is not restarted.
            primarySwatch: Colors.blue,
            // This makes the visual density adapt to the platform that you run
            // the app on. For desktop platforms, the controls will be smaller and
            // closer together (more dense) than on mobile platforms.
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: SplashScreen(),
        );
      }
    }
    
    class SplashScreen extends StatefulWidget {
      @override
      _SplashScreenState createState() => _SplashScreenState();
    }
    
    class _SplashScreenState extends State<SplashScreen> {
      String appDocPath;
    
      Future<void> getApplicationDirectoryPath() async {
        Directory appDocDir = await getApplicationDocumentsDirectory();
        appDocPath = appDocDir.path;
      }
    
      @override
      initState() {
        getApplicationDirectoryPath().then((_) {
          Navigator.pushReplacement(
              context,
              MaterialPageRoute(
                  builder: (BuildContext context) => Home(
                        appDocPath,
                      )));
        });
    
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Container();
      }
    }
    
    class Home extends StatefulWidget {
      final String appDocPath;
    
      Home(this.appDocPath);
      @override
      _HomeState createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      File _image;
    
      @override
      initState() {
        super.initState();
      }
    
      Future _getImage() async {
        final picker = ImagePicker();
    
        final pickedFile = await picker.getImage(source: ImageSource.gallery);
    
        if (pickedFile == null) return;
    
        _image = File(pickedFile.path);
    
        final fileName = 'background_image';
        final File localImage = await _image.copy('${widget.appDocPath}/$fileName');
    
    
        setState(() {
        });
      }
    
      @override
      Widget build(BuildContext context) {
        Image image;
        var hasLocalImage =
            File('${widget.appDocPath}/background_image').existsSync();
        if (hasLocalImage) {
          var bytes =
              File('${widget.appDocPath}/background_image').readAsBytesSync();
          image = Image.memory(bytes);
        }
    
        return new Scaffold(
            floatingActionButton: FloatingActionButton(
              onPressed: () {
                _getImage();
              },
            ),
            body: (File('${widget.appDocPath}/background_image').existsSync())
                ? Center(
                    child: image,
                  )
                : Text('NO PICTURE HAS BEEN SELECTED NOW OR IN THE PAST'));
      }
    }
    

    关于flutter - 从Flutter中的图库中保存ImagePicker图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64718180/

    相关文章:

    Flutter:如何知道 ListView 中的项目位置?

    layout - flutter |如何在任何叠加层之上显示 AlertDialog?

    flutter - 如何在 flutter 中获取移动国家代码

    html - dart中的路由器未捕获window.location.assign()

    android - java.lang.IllegalStateException : Reply already submitted -- When trying to call result. 多次成功?

    flutter test enterText on widget 扩展 EditableText "Bad state: No element": building editable text for mention

    Flutter TextField 清除按钮位置错误

    Flutter Scaffold.of(context).openDrawer() 不起作用

    dart - 尝试确定变量是否属于某种类型时出现语法错误

    android - GetCurrentLocation 在 Android 的调试中工作但在发布 apk 中不起作用