PickedImage 变得空

PickedImage getting null

我想在使用路径提供程序包从图库中选取图像后,将图像本地保存在设备上。但 _image 文件变量在 Selecting an Image From Gallery 后变为空。这就是屏​​幕一直卡在 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(),)
              ),
            ],
          ),
        ),
      ),
    );
  }
}

使用图像类型 PickedFile 类型。例如:

PickedFile _image;

  Future pickImageFromGallery(ImageSource source, BuildContext context) async {
    var _image = await ImagePicker.platform.pickImage(source: source);
    image = _image;
 
    _uploadImage(image, context);
  }

**获取图片路径:

imageFile.path

您的代码中有些地方是错误的:

  1. getImage() 函数不在您的 class 中,因此 setState 将不起作用。

  2. 您没有检查 ImagePicker.platform.pickImage() 的 return 值,因为它可能为空。在用它初始化文件之前你必须检查它。

  3. directory.toString() 不是 return 目录的路径,而是 return 的“目录:'/something'”。它是用来打印的。如果你想要实际的目录路径,你需要directory.path

  4. 如果仍然无法正常工作,请确保按照 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库。它允许您在缓存中存储和检索文件。

这是代码,已更新以将文件存储在缓存中。 请注意,我们使用密钥来标识缓存中的文件(我将其设置为文件的路径,但您基本上可以将其设置为任何字符串,只要它对该文件是唯一的即可)。如果您想在整个应用程序范围内使用该文件,您可能需要将密钥存储在可以在那里访问的地方。

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(),
                        )),
            ],
          ),
        ),
      ),
    );
  }
}