image_cropper_widget 1.0.1 copy "image_cropper_widget: ^1.0.1" to clipboard
image_cropper_widget: ^1.0.1 copied to clipboard

A customizable Flutter image cropper widget supporting aspect ratios, rotation, flipping, and custom UI overlay styles.

example/lib/main.dart

import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:image_cropper_widget/image_cropper_widget.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Image Cropper Demo',
      debugShowCheckedModeBanner: false,
      home: const MyHomePage(title: 'Image Cropper Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 1. Initialize the controller to manage the cropper state
  final _controller = ImageCropperController();
  CropperRatio? _aspectRatio;
  Uint8List? _croppedImage;
  HandleType _handleType = HandleType.corner;

  void _cropImage() async {
    // 2. Trigger the crop action
    final Uint8List? bytes = await _controller.crop();
    if (bytes != null) {
      setState(() {
        _croppedImage = bytes;
      });
      if (mounted) {
        showDialog(
          context: context,
          builder: (context) => AlertDialog(
            title: const Text('Cropped Image'),
            content: Image.memory(bytes),
            actions: [
              TextButton(
                onPressed: () => Navigator.pop(context),
                child: const Text('Close'),
              ),
            ],
          ),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: [
          IconButton(icon: const Icon(Icons.crop), onPressed: _cropImage),
        ],
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            Padding(
              padding: const EdgeInsets.all(16.0),
              child: ImageCropperWidget(
                // 3. Configure the view
                borderRadius: BorderRadius.circular(16.0),
                controller: _controller,
                image: const AssetImage('assets/sample-image.png'),
                aspectRatio: _aspectRatio,
                // 4. Customize the look and feel
                style: CropperStyle(
                  overlayColor: Colors.black54,
                  borderColor: Colors.white,
                  handlerColor: Colors.white,
                  borderWidth: 1.0,
                  handlerSize: 30,
                  handleType: _handleType,
                  handlerThickness: 6,
                ),
                loadingWidget: const Center(child: Text('Loading...')),
              ),
            ),

            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Wrap(
                runSpacing: 6,
                spacing: 6,
                children: CropperRatio.values.map((ratio) {
                  return _AspectRatioButton(
                    label: ratio.label,
                    onPressed: () {
                      // 5. Update aspect ratio programmatically
                      _controller.setAspectRatio(ratio);
                      setState(() => _aspectRatio = ratio);
                    },
                    isSelected: _aspectRatio == ratio,
                  );
                }).toList(),
              ),
            ),
            const SizedBox(height: 16),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                IconButton(
                  onPressed: () => _controller.rotateLeft(),
                  icon: const Icon(Icons.rotate_left),
                  tooltip: 'Rotate Left',
                ),
                IconButton(
                  onPressed: () => _controller.rotateRight(),
                  icon: const Icon(Icons.rotate_right),
                  tooltip: 'Rotate Right',
                ),
                IconButton(
                  onPressed: () => _controller.flipHorizontal(),
                  icon: const Icon(Icons.swap_horiz),
                  tooltip: 'Flip Horizontal',
                ),
                IconButton(
                  onPressed: () => _controller.flipVertical(),
                  icon: const Icon(Icons.swap_vert),
                  tooltip: 'Flip Vertical',
                ),
              ],
            ),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16.0),
              child: Row(
                children: [
                  const SizedBox(width: 20),
                  const Text('Handle Type: '),
                  const SizedBox(width: 10),
                  DropdownButton<HandleType>(
                    value: _handleType,
                    items: HandleType.values.map((type) {
                      return DropdownMenuItem(
                        value: type,
                        child: Text(type.name.toUpperCase()),
                      );
                    }).toList(),
                    onChanged: (value) {
                      if (value != null) {
                        setState(() {
                          _handleType = value;
                        });
                      }
                    },
                  ),
                ],
              ),
            ),
            const SizedBox(height: 20),
          ],
        ),
      ),
    );
  }
}

class _AspectRatioButton extends StatelessWidget {
  final String label;
  final VoidCallback onPressed;
  final bool isSelected;

  const _AspectRatioButton({
    required this.label,
    required this.onPressed,
    required this.isSelected,
  });

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: onPressed,
      style: ElevatedButton.styleFrom(
        backgroundColor: isSelected ? Theme.of(context).primaryColor : null,
        foregroundColor: isSelected ? Colors.white : null,
      ),
      child: Text(label),
    );
  }
}
2
likes
0
points
511
downloads

Publisher

verified publisherinfoowly.com

Weekly Downloads

A customizable Flutter image cropper widget supporting aspect ratios, rotation, flipping, and custom UI overlay styles.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter

More

Packages that depend on image_cropper_widget