image
image copied to clipboard
Crop Image
Hello, I'm working on the mobile application which have feature of scanning register plates with the following UI.
I was trying to crop focused part of the image with this package for the whole day, but without the success.
final image = await cameraController.takePicture(); final file = File(image.path); final bytes = file.readAsBytesSync(); final luka = img.Image.fromBytes( width: context.screenWidth.toInt(), height: context.screenHeight.toInt(), bytes: bytes.buffer, );
After executing Image.fromBytes method, I got picture like this:
Also, when I use Image.cropCopy method, I got picture like this:
Code for cropCopy:
final picture = img.copyCrop( img.Image.fromBytes( width: context.screenWidth.toInt(), height: context.screenHeight.toInt(), bytes: bytes.buffer, ), x: offset!.dx.toInt(), y: offset.dy.toInt(), width: context.screenWidth.toInt() - 100, height: 100, );
Does anyone know what I'm doing wrong?
My guess is the CameraController is saving to an image format, not raw RGB bytes. Do you still have an issue if you use img.decodeImage(bytes)?
Hi @brendan-duncan , sorry for the late response. Yes, CameraController is saving image as XFile. After calling decodeImage(), I can see image in correct format, but It doesn't crop focused area.
This is the code when the user taps on 'Take a photo' button:
final image = await cameraController.takePicture();
final offset = containerKey.globalPaintBounds;
final file = File(image.path);
final slika = img.decodeJpg(file.readAsBytesSync());
final picture = img.copyCrop(
img.Image.from(slika!),
x: offset!.dx.toInt(),
y: offset!.dy.toInt(),
width: context.screenWidth.toInt() - 100,
height: 100,
);
final path = Directory('/storage/emulated/0/Download/').path;
final jpg = img.encodeJpg(picture);
final pip = File('$path/text.jpg');
await pip.writeAsBytes(jpg);
This is how I get offset of the focused widget:
extension GlobalKeyExtension on GlobalKey {
Offset? get globalPaintBounds {
final renderObject = currentContext?.findRenderObject() as RenderBox;
Offset? position = renderObject.localToGlobal(Offset.zero);
// final translation = renderObject?.getTransformTo(null).getTranslation();
if (position != null) {
final offset = Offset(position.dx, position.dy);
return offset;
} else {
return null;
}
}
}
Focused widget:
class FocusedWidget extends StatelessWidget {
const FocusedWidget({super.key});
@override
Widget build(BuildContext context) {
return Container(
key: containerKey,
width: context.screenWidth - 100,
height: 100,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(10),
),
);
}
}
UI:
And after taking the photo, instead of getting the cropped image of focused part, I get the picture of this position:
Do you know maybe what is the problem? Do I provide correct values to the copyCrop method?
You're use of copyCrop is correct, other than there's no need to make a copy of the source image,
final picture = img.copyCrop(
slika!, // No need to make a copy of the image
x: offset!.dx.toInt(),
y: offset!.dy.toInt(),
width: context.screenWidth.toInt() - 100,
height: 100);
What's not clear is whether the offset and context.screenWidth values are correct. Can you verify they are correct and what you expect? They should be relative to the resolution of the slika image. Is context.screenWidth the same as slika.width? Maybe just use slika.width. Are the offsets correct? Maybe they are in a different coordinate system.
@lukajelacic I was having a similar issue, but when I realized that the image may be of a different dimension than that of the screen, things started adding up. In my case, the screen dimensions were Size(392.7, 781.1), and the image size was Size (720, 1280). So when I tried to use the screen dimensions, it was getting a different part of the image. Looking at the results, it was very clear that I was missing some transformation - and the transformation was just to ensure that the screen height and width matched to those of the image. See how I achieved it below.
double widthFactor = slika!.width / screenSize.width;
double heightFactor = slika.height / screenSize.height;
final picture = img.copyCrop(slika!,
x: (bounds.left * widthFactor).toInt(),
y: (bounds.top * heightFactor).toInt(),
width: ((bounds.right - bounds.left) * widthFactor ).toInt() ,
height: ((bounds.bottom - bounds.top) * heightFactor).toInt());
final dir = await getApplicationDocumentsDirectory();
final jpg = img.encodeJpg(picture);
final pip = File('${dir.path}cropped.jpg');
await pip.writeAsBytes(jpg);