我真的很困惑。颤抖真棒,但有些时间被困住了
所有代码均已完成。所选文件也显示在预览中,但我尝试将该文件保存在本地android存储中。我无法在
中获得成功 Future getImage(ImageSource imageSource) async {
var image = await ImagePicker.pickImage(source: imageSource);
setState(() {
_image = image;
});
}
使用此代码选择文件,然后将文件保存在_image
中,现在我尝试使用path_provider和dart.io
进行存储,但无法获得保存方法。
答案 0 :(得分:7)
使用await ImagePicker.pickImage(...)
,您已经在正确的轨道上,因为该函数返回了File
。
File
类具有一个copy
method,您可以使用它来复制文件(该文件已经通过相机或放在图库中保存在磁盘上)并放入了您的应用程序文档中目录:
// 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;
});
您还应该注意,您可以使用ImagePicker
从image.path
获取图像文件的路径,该路径还将包含您可能要提取的文件结尾,并且可以保存图像路径通过使用newImage.path
。
答案 1 :(得分:5)
自image_picker 0.6.7起
pickImage
,pickVideo
和retrieveLostData
已被弃用。
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);
}
一个更紧凑的示例:
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;
});
}
答案 2 :(得分:3)
希望能帮助和见到别人。给个喜欢。
RepaintBoundary
将为您提供帮助。
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!');
});
}
此文件为utils。
Flutter提供了一个RepaintBoundaryWidget来实现屏幕截图功能。
RepaintBoundary用于包装需要截取的部分。
RenderRepaintBoundary可用于截取由RepaintBoundary包装的部分。
然后通过使用boundary.toImage()方法将其转换为ui.Image对象,然后使用image.toByteData()将图像转换为byteData;
最后通过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;
}
答案 3 :(得分:2)
@creativecreatoror可能没有真正的帮助,但它错过了一个重要的部分,即检索图像供以后使用。
保存图像
// 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');
提示:您可以使用 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)
答案 4 :(得分:0)
要在本地保存文件,我们需要添加一些依赖
dependencies:
flutter:
sdk: flutter
path_provider:
path:
path_provider
找到存储图像的正确路径。
路径
创建适用于任何平台的路径。
示例:
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.');
}
});
答案 5 :(得分:0)
以下代码是空安全的,并将图像存储在设备的外部存储设备中,该设备可在 /storage/emulated/0/Android/data/<your-package>/files/name.png
中找到。
创建此方法:
Future<File?> captureAndSaveImage() async {
final pickedImage = await ImagePicker().getImage(source: ImageSource.camera);
if (pickedImage == null) return null;
try {
final directory = await getExternalStorageDirectory();
if (directory != null) return File(pickedImage.path).copy('${directory.path}/name.png');
} catch (e) {
return null;
}
}
用法:
File? file = await captureAndSaveImage();