Harsh Rajpara
Harsh Rajpara

Reputation: 79

Image crop using the container position in flutter

In this code, it works fine. but I have to change some.

In this code, one container fixed position, and in this container, one image is added. and one movable container, and one crop button.

but when click the crop button, the movable container image area is cut and shows the next screen.

----- I need this change----------

When click on the crop button, it crops the movable container image area but does not show to the new screen. show the crop image output in movable container with same position and the out side image is hidden. I have to add some images for the output I need.

import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
      home: Scaffold(body: ImageCrop(image: const AssetImage("images/rose1.png")))));
}

class ImageCrop extends StatefulWidget {
  const ImageCrop({Key? key, required this.image}) : super(key: key);
  final ImageProvider image;

  @override
  State<ImageCrop> createState() => _ImageCropState();
}

class _ImageCropState extends State<ImageCrop> {
  late ImageStream _imageStream;
  ui.Image? _image;
  late double _left;
  late double _top;
  late double _width;
  late double _height;

  @override
  void initState() {
    super.initState();
    _left = 0.0;
    _top = 0.0;
    _width = 100.0;
    _height = 100.0;

    // Call _getImage after initState is completed
    WidgetsBinding.instance?.addPostFrameCallback((_) {
      _getImage();
    });
  }

  void _getImage() {
    _imageStream = widget.image.resolve(createLocalImageConfiguration(context));
    _imageStream.addListener(ImageStreamListener(_updateImage));
  }

  void _updateImage(ImageInfo imageInfo, bool synchronousCall) {
    setState(() {
      _image = imageInfo.image;
    });
  }

  @override
  void didUpdateWidget(ImageCrop oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.image != oldWidget.image) {
      _imageStream.removeListener(ImageStreamListener(_updateImage));
      _imageStream =
          widget.image.resolve(createLocalImageConfiguration(context));
      _imageStream.addListener(ImageStreamListener(_updateImage));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Padding(
        padding: const EdgeInsets.only(top:50),
        child: Column(
          children: [
            ElevatedButton(
              onPressed: () async {
                final data = await _crop();
                Navigator.of(context).push(MaterialPageRoute(
                    builder: (ctx) => Scaffold(
                        appBar: AppBar(),
                        body: SizedBox.expand(
                            child: Container(
                                decoration:
                                    BoxDecoration(border: Border.all(width: 2)),
                                child: Image.memory(data!.buffer.asUint8List(),
                                    fit: BoxFit.contain))))));
              },
              child: const Text('crop'),
            ),
            Stack(
              children: [
                Container(
                  width: 200,
                  height: 200,
                  decoration: BoxDecoration(
                        border: Border.all(color: Colors.black)// Add border radius if needed
                  ),
                  child:
                      Image(image: widget.image, fit:BoxFit.contain,) // Load image from asset
                ),
                Positioned(
                  left: _left,
                  top: _top,
                  child: GestureDetector(
                    onPanUpdate: (details) {
                      setState(() {
                        _left += details.delta.dx;
                        _top += details.delta.dy;
                      });
                    },
                    child: Container(
                      width: _width,
                      height: _height,
                      decoration:
                          BoxDecoration(border: Border.all(color: Colors.black38)),
                    ),
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  Future<ByteData?> _crop() async {
    if (_image == null) return null;
    final scale = _image!.width / MediaQuery.of(context).size.width;
    final left = _left * scale;
    final top = _top * scale;
    final width = _width * scale;
    final height = _height * scale;
    final recorder = ui.PictureRecorder();
    final src = Rect.fromLTWH(left, top, width, height);
    final dst = Offset.zero & src.size;
    final canvas = Canvas(recorder, dst);
    canvas.drawImageRect(_image!, src, dst, Paint());
    final picture = recorder.endRecording();
    final cropped = await picture.toImage(width.toInt(), height.toInt());
    return await cropped.toByteData(format: ui.ImageByteFormat.png);
  }
}

enter image description here when the click crop button i have to show this output. enter image description here

Upvotes: 0

Views: 100

Answers (1)

Mohammad Soltani
Mohammad Soltani

Reputation: 73

You must change your onPressed method to:


    onPressed: () async {
                     await _crop().then((data){
                       Navigator.of(context).push(MaterialPageRoute(
                           builder: (ctx) => Scaffold(
                              appBar: AppBar(),
                              body: SizedBox.expand(
                                      child: Container(
                                      decoration: BoxDecoration(border: 
                                      Border.all(width: 2)),
                                      child: Image.memory(data!.buffer.asUint8List(),
                                        fit: BoxFit.contain))))));

});
                   
                  },

Upvotes: 0

Related Questions