如何在Flutter中保存图像文件?使用Image_picker插件选择文件

Rav*_*eri 8 dart flutter

我真的很困惑.颤抖是很棒的,但有些时间会让人头疼

所有代码都完成了.所选文件也在预览中显示但我尝试将该文件保存在本地Android存储中.我无法获得成功

  Future getImage(ImageSource imageSource) async {
    var image = await ImagePicker.pickImage(source: imageSource);

    setState(() {
      _image = image;
    });
  } 
Run Code Online (Sandbox Code Playgroud)

_image现在使用此代码和我的文件选择文件我尝试使用path_provider进行存储,dart.io但我无法获得保存方法.

Viv*_*sal 19

@creativecreatorormaybenot 答案确实很有帮助,但它错过了一个重要部分,即检索图像以供以后使用。

保存图像

// 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');
Run Code Online (Sandbox Code Playgroud)

提示:您可以使用basename(file.path)从原始文件中检索文件名。确保导入 'package:path/path.dart';

检索/加载图像

// 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)
Run Code Online (Sandbox Code Playgroud)


Ilk*_*Cat 15

从 image_picker 0.6.7 开始

pickImagepickVideoretrieveLostData弃用
https://pub.dev/packages/image_picker#-changelog-tab-

这些方法必须替换为

  • getImage
  • getVideo
  • getLostData

getImage()方法的示例用法:

...
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);
}
Run Code Online (Sandbox Code Playgroud)

一个稍微紧凑一点的例子

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;
  });
}
Run Code Online (Sandbox Code Playgroud)


cre*_*not 13

使用await ImagePicker.pickImage(...),你已经在正确的轨道,因为该函数返回一个File.

File类有一个copy方法,你可以用它来复制文件(已经由相机要么或躺在库保存在磁盘上),并把它放到你的申请文件目录:

// 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;
});
Run Code Online (Sandbox Code Playgroud)

您还应该注意,您可以从ImagePicker使用中获取图像文件的路径image.path,其中还包含您可能要提取的文件结尾,您可以使用保存图像路径newImage.path.

  • 如何检索此文件并稍后显示给用户?我可以使用哪种文件读取操作? (4认同)
  • 我们可以将文件的“路径”保存为字符串,然后可以使用类似 File(path) 的路径检索文件。使用这个方便的方法加载图像 FileImage(File(path))。 (2认同)

小智 7

希望能帮助到看到的人\xe3\x80\x82点个赞\xe3\x80\x82

\n\n

RepaintBoundary会帮助你\xe3\x80\x82

\n\n
final GlobalKey _repaintKey = new GlobalKey();\n\n\n//  Image Widget\n\n\nWidget _buildQrImage() {\n_avatar = RepaintBoundary(\n  key: _repaintKey,\n  child: Image.asset(\'assets/ifredom.jpg\')\n);\n\nreturn Column(\n  children: <Widget>[\n    _avatar,\n    (imageFile == null)\n        ? Image.asset(\'assets/default.jpg\')\n        : Image.file(imageFile),\n    FlatButton(\n      child: Text("save"),\n      onPressed: () {\n        _saveScreenShot(context);\n      },\n    ),\n\n  ],\n);\n}\n\n\n\nvoid _saveScreenShot(BuildContext context) {\nRenderRepaintBoundary boundary = _repaintKey.currentContext.findRenderObject();\n\n// ScreenShot and save\nsaveScreenShot(boundary, success: () {\n  saveScreenShot2SDCard(boundary, success: () {\n    showToast(\'save ok\');\n  }, fail: () {\n    showToast(\'save ok\');\n  });\n}, fail: () {\n  showToast(\'save fail!\');\n});\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这个文件是utils.

\n\n

Flutter提供了一个RepaintBoundaryWidget来实现截图功能。

\n\n

RepaintBoundary用于包裹需要截取的部分。

\n\n

RenderRepaintBoundary 可用于拦截 RepaintBoundary 包裹的部分。

\n\n

然后通过boundary.toImage()方法转换为ui.Image对象,然后image.toByteData()将图像转换为byteData;

\n\n

最后通过File()将其存储为文件对象。WriteAsBytes():

\n\n
import \'dart:async\';\nimport \'dart:io\';\nimport \'dart:typed_data\';\nimport \'dart:ui\' as ui;\n\nimport \'package:flutter/rendering.dart\';\nimport \'package:path_provider/path_provider.dart\';\nimport \'package:permission_handler/permission_handler.dart\';\n\nimport \'package:oktoast/oktoast.dart\';\n\nfinal String scrawlImagePath = \'/screen_shot_scraw.png\';\n\n\nFuture<File> getScreenShotFile() async {\n  Directory tempDir = await getTemporaryDirectory();\n  String tempPath = \'${tempDir.path}$scrawlImagePath\';\n  File image = File(tempPath);\n  bool isExist = await image.exists();\n  return isExist ? image : null;\n}\n\nFuture saveScreenShot2SDCard(RenderRepaintBoundary boundary,\n    {Function success, Function fail}) async {\n  // check storage permission.\n  PermissionHandler().requestPermissions([PermissionGroup.storage]).then((map) {\n    if (map[PermissionGroup.storage] == PermissionStatus.granted) {\n      capturePng2List(boundary).then((uint8List) async {\n        if (uint8List == null || uint8List.length == 0) {\n          if (fail != null) fail();\n          return;\n        }\n        Directory tempDir = await getExternalStorageDirectory();\n        _saveImage(uint8List, Directory(\'${tempDir.path}/flutter_ui\'),\n            \'/screen_shot_scraw_${DateTime.now()}.png\',\n            success: success, fail: fail);\n      });\n    } else {\n      showToast(\'\xe8\xaf\xb7\xe6\x89\x93\xe5\xbc\x80SD\xe5\x8d\xa1\xe5\xad\x98\xe5\x82\xa8\xe6\x9d\x83\xe9\x99\x90\xef\xbc\x81\');\n//      if (fail != null) fail();\n      return;\n    }\n  });\n}\n\nvoid saveScreenShot(RenderRepaintBoundary boundary,\n    {Function success, Function fail}) {\n  capturePng2List(boundary).then((uint8List) async {\n    if (uint8List == null || uint8List.length == 0) {\n      if (fail != null) fail();\n      return;\n    }\n    Directory tempDir = await getTemporaryDirectory();\n    _saveImage(uint8List, tempDir, scrawlImagePath,\n        success: success, fail: fail);\n  });\n}\n\nvoid _saveImage(Uint8List uint8List, Directory dir, String fileName,\n    {Function success, Function fail}) async {\n  bool isDirExist = await Directory(dir.path).exists();\n  if (!isDirExist) Directory(dir.path).create();\n  String tempPath = \'${dir.path}$fileName\';\n  File image = File(tempPath);\n  bool isExist = await image.exists();\n  if (isExist) await image.delete();\n  File(tempPath).writeAsBytes(uint8List).then((_) {\n    if (success != null) success();\n  });\n}\n\nFuture<Uint8List> capturePng2List(RenderRepaintBoundary boundary) async {\n  ui.Image image =\n      await boundary.toImage(pixelRatio: ui.window.devicePixelRatio);\n  ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);\n  Uint8List pngBytes = byteData.buffer.asUint8List();\n  return pngBytes;\n}\n
Run Code Online (Sandbox Code Playgroud)\n


jit*_*555 5

为了将文件保存到本地,我们需要添加一些依赖项

dependencies:
  flutter:
    sdk: flutter
  path_provider:
  path:
Run Code Online (Sandbox Code Playgroud)

路径提供者

找到存储图像的正确路径。

小路

创建适用于任何平台的路径。


例子:

final pickedFile = await picker.getImage(source: ImageSource.camera);
_image = File(pickedFile.path);

// getting a directory path for saving
final Directory extDir = await getApplicationDocumentsDirectory();
String dirPath = extDir.path;
final String filePath = '$dirPath/image.png';

// copy the file to a new path
final File newImage = await _image.copy(filePath);
setState(() {
  if (pickedFile != null) {
    _image = newImage;
  } else {
    print('No image selected.');
  }
});
Run Code Online (Sandbox Code Playgroud)