Flutter 保存和加载图像 - 图像 Picker/Image 裁剪

Flutter Save & Load Image - Image Picker/Image crop

我正在尝试在 flutter 中制作个人资料图片屏幕。我已将这 2 个插件(图像裁剪和图像选择器)用于 select 并编辑图像。

class ProfilePage extends StatefulWidget {
  @override
  __ProfilePageState createState() => __ProfilePageState();
}

class __ProfilePageState extends State<ProfilePage> {
  File _pickedImage;
  String _imagepath;

  @override
  void initState() {
    super.initState();
    LoadImage();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
//      appBar: AppBar(
//        title: Text('Profile'),
//      ),
      body: ListView(
        children: <Widget>[
          Center(
            child: CircleAvatar(
              radius: 80,
              child: _imagepath == null ? Text('Profile image') : null,
              backgroundImage:
                  _imagepath != null ? FileImage(File(_imagepath)) : null,
            ),
          ),
          SizedBox(height: 10),
          RaisedButton(
            child: Text('Select image'),
            onPressed: () {
              _showPickOptionDialog(context);
            },
          )
        ],
      ),
    );
  }

  _loadPicker(ImageSource source) async {
    File picked = await ImagePicker.pickImage(source: source);

    if (picked != null) {
      _cropImage(picked);
      SaveImage(picked.path);
    }
    LoadImage();
    Navigator.pop(context);
  }

  _cropImage(File picked) async {
    File cropped = await ImageCropper.cropImage(
      androidUiSettings: AndroidUiSettings(
        toolbarTitle: "Modifica immagine",
        statusBarColor: Colors.green,
        toolbarColor: Colors.green,
        toolbarWidgetColor: Colors.white,
      ),
      sourcePath: picked.path,
//      aspectRatioPresets: [
//        CropAspectRatioPreset.original,
//        CropAspectRatioPreset.ratio16x9,
//        CropAspectRatioPreset.ratio4x3,
//      ],
      maxWidth: 800,
    );
    if (cropped != null) {
      setState(() {
        _pickedImage = cropped;
      });
    }
  }

  void _showPickOptionDialog(BuildContext context) {
    showDialog(
        context: context,
        builder: (context) => AlertDialog(
              content: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  ListTile(
                      title: Text('select image from gallery'),
                      onTap: () {
                        _loadPicker(ImageSource.gallery);
                      }),
                  ListTile(
                    title: Text('Scatta una foto'),
                    onTap: () {
                      _loadPicker(ImageSource.camera);
                    },
                  ),
                ],
              ),
            ));
  }

  void SaveImage(path) async {
    SharedPreferences saveimage = await SharedPreferences.getInstance();
    saveimage.setString("imagepath", path);
  }

  void LoadImage() async {
    SharedPreferences saveimage = await SharedPreferences.getInstance();
    setState(() {
      _imagepath = saveimage.getString("imagepath");
    });
  }
}

代码有效,但它只保存选取的图像而不是裁剪后的图像。

试了很多次都看不到错误,抱歉..

你能帮帮我吗?

谢谢!

当您使用 Future 时,您应该 return 值并将此值与 .then() 一起使用
试试这个:

class ProfilePage extends StatefulWidget {
  @override
  __ProfilePageState createState() => __ProfilePageState();
}

class __ProfilePageState extends State<ProfilePage> {
  File _pickedImage;
  String _imagepath;

  @override
  void initState() {
    super.initState();
    LoadImage();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
//      appBar: AppBar(
//        title: Text('Profile'),
//      ),
      body: ListView(
        children: <Widget>[
          Center(
            child: CircleAvatar(
              radius: 80,
              child: _imagepath == null ? Text('Profile image') : null,
              backgroundImage:
                  _imagepath != null ? FileImage(File(_imagepath)) : null,
            ),
          ),
          SizedBox(height: 10),
          RaisedButton(
            child: Text('Select image'),
            onPressed: () {
              _showPickOptionDialog(context);
            },
          )
        ],
      ),
    );
  }

  _loadPicker(ImageSource source) async {
    File picked = await ImagePicker.pickImage(source: source);

    if (picked != null) {
      _cropImage(picked).then(File cropped){
         SaveImage(cropped.path);
      }

    }
    LoadImage();
    Navigator.pop(context);
  }

  Future<File> _cropImage(File picked) async {
    File cropped = await ImageCropper.cropImage(
      androidUiSettings: AndroidUiSettings(
        toolbarTitle: "Modifica immagine",
        statusBarColor: Colors.green,
        toolbarColor: Colors.green,
        toolbarWidgetColor: Colors.white,
      ),
      sourcePath: picked.path,
//      aspectRatioPresets: [
//        CropAspectRatioPreset.original,
//        CropAspectRatioPreset.ratio16x9,
//        CropAspectRatioPreset.ratio4x3,
//      ],
      maxWidth: 800,
    );
    if (cropped != null) {
      setState(() {
        _pickedImage = cropped;
      });
    }
   return cropped;
  }

  void _showPickOptionDialog(BuildContext context) {
    showDialog(
        context: context,
        builder: (context) => AlertDialog(
              content: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  ListTile(
                      title: Text('select image from gallery'),
                      onTap: () {
                        _loadPicker(ImageSource.gallery);
                      }),
                  ListTile(
                    title: Text('Scatta una foto'),
                    onTap: () {
                      _loadPicker(ImageSource.camera);
                    },
                  ),
                ],
              ),
            ));
  }

  void SaveImage(path) async {
    SharedPreferences saveimage = await SharedPreferences.getInstance();
    saveimage.setString("imagepath", path);
  }

  void LoadImage() async {
    SharedPreferences saveimage = await SharedPreferences.getInstance();
    setState(() {
      _imagepath = saveimage.getString("imagepath");
    });
  }
}

通过编辑这部分找到解决方案:

 if (cropped != null) {
  _pickedImage = cropped;
  SaveImage(_pickedImage.path);
  LoadImage();
  setState(() {});
}

}