我想在使用路径提供程序包从图库中选取图像后将图像保存在设备本地。但在从图库中选择图像后 _image 文件变量变为 null 。这就是屏幕始终卡在 CircularProgressIndicator Screen 上的原因。你能帮我摆脱这个 null _image 文件变量吗?
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
class SaveImage extends StatefulWidget {
const SaveImage({ Key? key }) : super(key: key);
@override
_SaveImageState createState() => _SaveImageState();
}
File? _image;
Future<File?> getImage() async{
var image = File(await ImagePicker.platform
.pickImage(source: ImageSource.gallery)
.then((value) => value.path));
final Directory directory = await getApplicationDocumentsDirectory();
final path=directory.toString();
final String fileName = basename(image.path);
// final String fileExtension = extension(image.path);
File newImage = await image.copy('$path/$fileName.jpg');
setState(() {
_image = newImage;
});
}
void setState(Null Function() param0) {
}
class _SaveImageState extends State<SaveImage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
children: [
Text('Pick Image From'),
SizedBox(height: 30,),
ElevatedButton(onPressed: (){
getImage();
}, child: Text('From Gallery')),
ElevatedButton(onPressed: (){
}, child: Text('From Camera')),
SizedBox(height: 50),
Container(
child: _image!=null?ClipRRect(
borderRadius: BorderRadius.circular(6),
child: Image.file(
_image!,
fit: BoxFit.cover,
)):Center(child: CircularProgressIndicator(),)
),
],
),
),
),
);
}
}
最佳答案
您的代码中有一些问题:
getImage()
函数不在您的类中,因此 setState 不起作用。您没有检查
ImagePicker.platform.pickImage()
的返回值,因为它可能为 null。您必须在用它初始化文件之前检查它。directory.toString()
不返回目录的路径,但返回“Directory: '/something'”。它是要打印的。如果您想要实际的目录路径,则需要directory.path
如果仍然无法正常工作,请确保您已按照 image_picker 的要求进行了正确的设置(为 IOS 设置 Info.plist...)
这是您的代码,按预期工作:
class SaveImage extends StatefulWidget {
const SaveImage({Key? key}) : super(key: key);
@override
_SaveImageState createState() => _SaveImageState();
}
class _SaveImageState extends State<SaveImage> {
File? _image;
Future<File?> getImage() async {
PickedFile? pickedFile =
await ImagePicker.platform.pickImage(source: ImageSource.gallery);
if (pickedFile == null) {
return null;
}
final File file = File(pickedFile.path);
final Directory directory = await getApplicationDocumentsDirectory();
final path = directory.path;
final String fileName = basename(pickedFile.path);
// final String fileExtension = extension(image.path);
File newImage = await file.copy('$path/$fileName');
setState(() {
_image = newImage;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
children: [
Text('Pick Image From'),
SizedBox(
height: 30,
),
ElevatedButton(
onPressed: () {
getImage();
},
child: Text('From Gallery')),
ElevatedButton(onPressed: () {}, child: Text('From Camera')),
SizedBox(height: 50),
Container(
child: _image != null
? ClipRRect(
borderRadius: BorderRadius.circular(6),
child: Image.file(
_image!,
fit: BoxFit.cover,
))
: Center(
child: CircularProgressIndicator(),
)),
],
),
),
),
);
}
}
如果要将图像存储在缓存中,可以使用 flutter_cache_manager 库。它允许您在缓存中存储和检索文件。
这是代码,已更新以将文件存储在缓存中。 请注意,我们使用一个键来标识缓存中的文件(我将其设置为文件的路径,但您可以将其设置为基本上任何字符串,只要它对于该文件是唯一的)。如果您想在应用程序范围内使用该文件,您可能需要将 key 存储在可以访问的地方。
class SaveImage extends StatefulWidget {
const SaveImage({Key? key}) : super(key: key);
@override
_SaveImageState createState() => _SaveImageState();
}
class _SaveImageState extends State<SaveImage> {
File? _image;
String? cachedFileKey;
Future<File?> getImage() async {
PickedFile? pickedFile =
await ImagePicker.platform.pickImage(source: ImageSource.gallery);
if (pickedFile == null) {
return null;
}
final File file = File(pickedFile.path);
final Uint8List fileBytes = await file.readAsBytes();
final cachedFile = await DefaultCacheManager()
.putFile(pickedFile.path, fileBytes, key: pickedFile.path);
setState(() {
cachedFileKey = pickedFile.path;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
children: [
Text('Pick Image From'),
SizedBox(
height: 30,
),
ElevatedButton(
onPressed: () {
getImage();
},
child: Text('From Gallery')),
ElevatedButton(onPressed: () {}, child: Text('From Camera')),
const SizedBox(height: 50),
Container(
child: cachedFileKey != null
?
FutureBuilder<FileInfo?>(future: DefaultCacheManager().getFileFromCache(cachedFileKey!), builder: (context, snapShot) {
if (snapShot.hasData && snapShot.data != null) {
return ClipRRect(
borderRadius: BorderRadius.circular(6),
child: Image.file(snapShot.data!.file,
fit: BoxFit.cover,
));
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
})
: const Center(
child: CircularProgressIndicator(),
)),
],
),
),
),
);
}
}
关于flutter - PickedImage 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70701299/