How to Save Image File in Flutter ? File selected using Image_picker plugin

后端 未结 4 964
醉梦人生
醉梦人生 2020-12-04 18:59

I am really confused. Flutter is awesome but some time is stuck the mind

All the code are done. selected file also showing in preview but I try to save that file in

相关标签:
4条回答
  • 2020-12-04 19:11

    As of image_picker 0.6.7

    pickImage, pickVideo and retrieveLostData are deprecated.
    https://pub.dev/packages/image_picker#-changelog-tab-

    Those methods have to be replaced by

    • getImage
    • getVideo
    • getLostData

    An example usage of the getImage() method:

    ...
    File _storedImage;
    ...
    
    void _takePicture() async {
      // 1. Create an ImagePicker instance.
      final ImagePicker _picker = ImagePicker();
    
      // 2. Use the new method.
      //
      // getImage now returns a PickedFile instead of a File (form dart:io)
      final PickedFile pickedImage = await _picker.getImage(...)
    
      // 3. Check if an image has been picked or take with the camera.
      if (pickedImage == null) {
        return;
      }
    
      // 4. Create a File from PickedFile so you can save the file locally
      // This is a new/additional step.
      File tmpFile = File(pickedFile.path);
    
      // 5. Get the path to the apps directory so we can save the file to it.
      final String path = await getApplicationDocumentsDirectory().path;
      final String fileName = basename(pickedFile.path); // Filename without extension
      final String fileExtension = extension(pickedFile.path); // e.g. '.jpg'
    
      // 6. Save the file by copying it to the new location on the device.
      tmpFile = await tmpFile.copy('$path/$fileName$fileExtension');
    
      // 7. Optionally, if you want to display the taken picture we need to update the state
      // Note: Copying and awaiting the file needs to be done outside the setState function.
      setState(() => _storedImage = tmpFile);
    }
    

    A slightly more compact example:

    File _image;
    final picker = ImagePicker();
    
    Future getImage() async {
      final File pickedImage = await picker.getImage(source: ImageSource.camera);
    
      if (pickedImage == null) return;
    
      File tmpFile = File(pickedImage.path);
      tmpFile = await tmpFile.copy(tmpFile.path);
    
      setState(() {
        _image = tmpFile;
      });
    }
    
    0 讨论(0)
  • 2020-12-04 19:31

    Using await ImagePicker.pickImage(...), you are already on the right track because the function returns a File.

    The File class has a copy method, which you can use to copy the file (which is already saved on disk by either the camera or by lying in gallery) and put it into your application documents directory:

    // using your method of getting an image
    final File image = await ImagePicker.pickImage(source: imageSource);
    
    // getting a directory path for saving
    final String path = await getApplicationDocumentsDirectory().path;
    
    // copy the file to a new path
    final File newImage = await image.copy('$path/image1.png');
    
    setState(() {
      _image = newImage;
    });
    

    You should also note that you can get the path of the image file from ImagePicker using image.path, which will also contain the file ending that you might want to extract and you can save your image path by using newImage.path.

    0 讨论(0)
  • 2020-12-04 19:33

    @creativecreatorormaybenot answer is really helpful but it missed one important part i.e retrieving the image for later use.

    Saving Image

    // Step 1: Retrieve image from picker 
    final File image = await ImagePicker.pickImage(source: imageSource);
    
    // Step 2: Check for valid file
    if (image == null) return;
    
    // Step 3: Get directory where we can duplicate selected file.
    final String path = await getApplicationDocumentsDirectory().path;
    
    // Step 4: Copy the file to a application document directory. 
    final var fileName = basename(file.path);
    final File localImage = await image.copy('$path/$fileName');
    

    Tip: you can retrieve file name from original file using basename(file.path). Make sure you import 'package:path/path.dart';

    Retrieving/Loading Image

    // Step 1: Save image/file path as string either db or shared pref
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setString('test_image', localImage.path)
    
    // Step 2: Loading image by using the path that we saved earlier. We can create a file using path 
    //         and can use FileImage provider for loading image from file.
    CircleAvatar(
              backgroundImage: FileImage(File(prefs.getString('test_image')),
              radius: 50,
              backgroundColor: Colors.white)
    
    0 讨论(0)
  • 2020-12-04 19:36

    Hope to help and see people。give a like。

    RepaintBoundary will help you。

    final GlobalKey _repaintKey = new GlobalKey();
    
    
    //  Image Widget
    
    
    Widget _buildQrImage() {
    _avatar = RepaintBoundary(
      key: _repaintKey,
      child: Image.asset('assets/ifredom.jpg')
    );
    
    return Column(
      children: <Widget>[
        _avatar,
        (imageFile == null)
            ? Image.asset('assets/default.jpg')
            : Image.file(imageFile),
        FlatButton(
          child: Text("save"),
          onPressed: () {
            _saveScreenShot(context);
          },
        ),
    
      ],
    );
    }
    
    
    
    void _saveScreenShot(BuildContext context) {
    RenderRepaintBoundary boundary = _repaintKey.currentContext.findRenderObject();
    
    // ScreenShot and save
    saveScreenShot(boundary, success: () {
      saveScreenShot2SDCard(boundary, success: () {
        showToast('save ok');
      }, fail: () {
        showToast('save ok');
      });
    }, fail: () {
      showToast('save fail!');
    });
    }
    

    this file is utils.

    Flutter provides a RepaintBoundaryWidget to implement the screenshot function.

    RepaintBoundary is used to wrap the part that needs to be intercepted.

    RenderRepaintBoundary can be used to intercept the part that is wrapped by RepaintBoundary.

    Then it is converted into a ui.Image object by using the boundary.toImage () method, and then image.toByteData ( ) Convert the image to byteData;

    finally store it as a file object via File (). WriteAsBytes ():

    import 'dart:async';
    import 'dart:io';
    import 'dart:typed_data';
    import 'dart:ui' as ui;
    
    import 'package:flutter/rendering.dart';
    import 'package:path_provider/path_provider.dart';
    import 'package:permission_handler/permission_handler.dart';
    
    import 'package:oktoast/oktoast.dart';
    
    final String scrawlImagePath = '/screen_shot_scraw.png';
    
    
    Future<File> getScreenShotFile() async {
      Directory tempDir = await getTemporaryDirectory();
      String tempPath = '${tempDir.path}$scrawlImagePath';
      File image = File(tempPath);
      bool isExist = await image.exists();
      return isExist ? image : null;
    }
    
    Future saveScreenShot2SDCard(RenderRepaintBoundary boundary,
        {Function success, Function fail}) async {
      // check storage permission.
      PermissionHandler().requestPermissions([PermissionGroup.storage]).then((map) {
        if (map[PermissionGroup.storage] == PermissionStatus.granted) {
          capturePng2List(boundary).then((uint8List) async {
            if (uint8List == null || uint8List.length == 0) {
              if (fail != null) fail();
              return;
            }
            Directory tempDir = await getExternalStorageDirectory();
            _saveImage(uint8List, Directory('${tempDir.path}/flutter_ui'),
                '/screen_shot_scraw_${DateTime.now()}.png',
                success: success, fail: fail);
          });
        } else {
          showToast('请打开SD卡存储权限!');
    //      if (fail != null) fail();
          return;
        }
      });
    }
    
    void saveScreenShot(RenderRepaintBoundary boundary,
        {Function success, Function fail}) {
      capturePng2List(boundary).then((uint8List) async {
        if (uint8List == null || uint8List.length == 0) {
          if (fail != null) fail();
          return;
        }
        Directory tempDir = await getTemporaryDirectory();
        _saveImage(uint8List, tempDir, scrawlImagePath,
            success: success, fail: fail);
      });
    }
    
    void _saveImage(Uint8List uint8List, Directory dir, String fileName,
        {Function success, Function fail}) async {
      bool isDirExist = await Directory(dir.path).exists();
      if (!isDirExist) Directory(dir.path).create();
      String tempPath = '${dir.path}$fileName';
      File image = File(tempPath);
      bool isExist = await image.exists();
      if (isExist) await image.delete();
      File(tempPath).writeAsBytes(uint8List).then((_) {
        if (success != null) success();
      });
    }
    
    Future<Uint8List> capturePng2List(RenderRepaintBoundary boundary) async {
      ui.Image image =
          await boundary.toImage(pixelRatio: ui.window.devicePixelRatio);
      ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
      Uint8List pngBytes = byteData.buffer.asUint8List();
      return pngBytes;
    }
    
    0 讨论(0)
提交回复
热议问题