Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I Crop Images in Flutter?

Tags:

image

flutter

I searching an days for this question.

I want to Crop Images like that, in flutter:

enter image description here

GIF Source: https://github.com/ArthurHub/Android-Image-Cropper

The closest lib for this solution is the Image Lib, that lib offers manipulate images and crop, but i want to crop images in UI level like this gif. All libs I found dont offers that.

like image 437
Eduardo Yamauchi Avatar asked Jun 22 '18 13:06

Eduardo Yamauchi


1 Answers

There is no widget that performs all that for you. However, I believe that it is possible to write that natively in flutter now. I don't have time at this particular moment to do it for you, but I can definitely point you in the right direction.

  1. You're going to need to load the image in such a way that you can either draw it onto a canvas or use a RawImage to draw it rather than using the Image widget directly.
  2. You need to figure out a co-ordinate system relative to the image
  3. You'll need to find a way of drawing the crop indicator - you could do this either by drawing directly on the canvas or possibly using some combination of GestureDetector/Draggable/DropTarget. I'd suggest that sticking to Canvas might be the easiest to start.
  4. Once the user has selected a part of the image, you need to translate the screen co-ordinates to picture co-ordinates.
  5. You then have to create an off-screen canvas to draw the cropped image to. There are various transforms you'll have to do to makes sure the image ends up in the right place.
  6. Once you've made the off-screen crop, you'll have to display the new image.

All of that is quite a lot of work, and probably a lot of finessing to get right.

Here's examples for a couple of the steps you'll need to do, but you'll have to figure out how to put them together.

Loading an image:

var byteData = await rootBundle.load("assets/image.jpg");
Uint8List lst = new Uint8List.view(byteData.buffer);
var codec = await UI.instantiateImageCodec(lst);
var nextFrame = await codec.getNextFrame();
var image = frameInfo.image;

Displaying an image on a canvas:

  • https://docs.flutter.io/flutter/dart-ui/Canvas/drawImageRect.html
  • https://docs.flutter.io/flutter/rendering/CustomPainter-class.html

Writing an image to a off-screen canvas:

ui.Image getCroppedImage(Image image, Rect src, Rect dst) {
  var pictureRecorder = new ui.PictureRecorder();
  Canvas canvas = new Canvas(pictureRecorder);
  canvas.drawImageRect(image, src, dst, Paint());
  return pictureRecorder.endRecording().toImage(dst.width.floor(), dst.height.floor());
}

You'll probably need to do something like this answer for getting the local coordinates of mouse/touch gestures.

Some advice - I'd start as simple as possible, not thinking about performance to start (i.e. draw everything each paint if needed, etc). Then once you get the basics working you can start thinking of optimization (i.e. using a RawImage, Transform, and Stack for the image and only re-drawing the selector, etc).

If you need any additional help let me know in a comment and I'll do my best to answer. Now that I've been writing about this a bit it does make me slightly curious to try implementing it so I may try at some point, but it probably won't be soon as I'm quite low on time at the moment. Good luck =D

like image 50
rmtmckenzie Avatar answered Dec 26 '22 07:12

rmtmckenzie