Hi, would somebody point me in the right direction please. I'm trying to learn as I go (yes I am a noob to coding and fumbling my way around) but I have managed to get this package running and accepting an image I upload...
Can anybody help me to save the final cropped image in to an app/local state please. I've tried putting this in (or variations of it) but it could be completely wrong...
FFAppState().update( () {setState( () => FFAppState().outputImage = image); } );
Here is my current working widget code without any app/local state workings...
// Automatic FlutterFlow imports import '/backend/backend.dart'; import '/flutter_flow/flutter_flow_theme.dart'; import '/flutter_flow/flutter_flow_util.dart'; import '/custom_code/widgets/index.dart'; // Imports other custom widgets import '/custom_code/actions/index.dart'; // Imports custom actions import '/flutter_flow/custom_functions.dart'; // Imports custom functions import 'package:flutter/material.dart'; // Begin custom widget code // DO NOT REMOVE OR MODIFY THE CODE ABOVE! import 'package:crop_image/crop_image.dart'; class Cropimage extends StatefulWidget { const Cropimage({ Key? key, this.width, this.height, this.imageURL, }) : super(key: key); final double? width; final double? height; final String? imageURL; @override _CropimageState createState() => _CropimageState(); } class _CropimageState extends State<Cropimage> { final controller = CropController( aspectRatio: 0.7782, defaultCrop: const Rect.fromLTRB(0.1, 0.1, 0.9, 0.9), ); // Local state to hold the cropped image Image? outputImage; @override Widget build(BuildContext context) => Scaffold( body: Center( child: CropImage( controller: controller, image: Image.network(widget.imageURL!), paddingSize: 0, alwaysMove: false, minimumImageSize: 500, ), ), bottomNavigationBar: _buildButtons(), ); Widget _buildButtons() => Row( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.center, children: [ TextButton( onPressed: _finished, child: const Text('Done'), ), ], ); Future<void> _aspectRatios() async { final value = await showDialog<double>( context: context, builder: (context) { return SimpleDialog( title: const Text('Select aspect ratio'), children: [ // special case: no aspect ratio SimpleDialogOption( onPressed: () => Navigator.pop(context, -1.0), child: const Text('free'), ), SimpleDialogOption( onPressed: () => Navigator.pop(context, 1.0), child: const Text('square'), ), SimpleDialogOption( onPressed: () => Navigator.pop(context, 2.0), child: const Text('2:1'), ), SimpleDialogOption( onPressed: () => Navigator.pop(context, 1 / 2), child: const Text('1:2'), ), SimpleDialogOption( onPressed: () => Navigator.pop(context, 4.0 / 3.0), child: const Text('4:3'), ), SimpleDialogOption( onPressed: () => Navigator.pop(context, 16.0 / 9.0), child: const Text('16:9'), ), ], ); }, ); if (value != null) { controller.aspectRatio = value == -1 ? null : value; controller.crop = const Rect.fromLTRB(0.1, 0.1, 0.9, 0.9); } } Future<void> _rotateLeft() async => controller.rotateLeft(); Future<void> _rotateRight() async => controller.rotateRight(); Future<void> _finished() async { final image = await controller.croppedImage(); // ignore: use_build_context_synchronously await showDialog<bool>( context: context, builder: (context) { return SimpleDialog( contentPadding: const EdgeInsets.all(6.0), titlePadding: const EdgeInsets.all(8.0), title: const Text('Cropped image'), children: [ Text('relative: ${controller.crop}'), Text('pixels: ${controller.cropSize}'), const SizedBox(height: 5), image, TextButton( onPressed: () => Navigator.pop(context, true), child: const Text('OK'), ), ], ); }, ); } }
I basically have a button with an action to upload a file via camera/gallery, then on the same chain it opens up a bottom sheet which has this widget in it. Ideally when the user does their crop, the bottom sheet will close and then I can display the cropped output from the app/local state (in theory)
Any help would be most appreciated... ELI5 π
Thanks