Flutter how to draw pressable rectangle on camera feed?

1,991

Camera plugin does not have any feature to draw over the preview, but you can make something like that with Stack widget and containers.

Here's a quick and dirty example, but hopefully will give you the idea:

class CameraApp extends StatefulWidget {
  @override
  _CameraAppState createState() => _CameraAppState();
}

class _CameraAppState extends State<CameraApp> {
  CameraController controller;

  // Holds the position information of the rectangle
  Map<String, double> _position = {
    'x': 0,
    'y': 0,
    'w': 0,
    'h': 0,
  };

  // Whether or not the rectangle is displayed
  bool _isRectangleVisible = false;

  Future<void> getCameras() async {
    final cameras = await availableCameras();
    controller = CameraController(cameras[0], ResolutionPreset.medium);
    controller.initialize().then((_) {
      if (!mounted) {
        return;
      }
      setState(() {});
    });
  }

  // Some logic to get the rectangle values
  void updateRectanglePosition() {
    setState(() {
      // assign new position
      _position = {
        'x': 0,
        'y': 0,
        'w': 0,
        'h': 0,
      };
      _isRectangleVisible = true;
    });
  }

  @override
  void initState() {
    getCameras();
    super.initState();
  }

  @override
  void dispose() {
    controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (!controller.value.isInitialized) {
      return Container();
    }
    return Stack(
      children: [
        AspectRatio(
          aspectRatio: controller.value.aspectRatio,
          child: controller == null ? Container() : CameraPreview(controller),
        ),
        if (_isRectangleVisible)
          Positioned(
            left: _position['x'],
            top: _position['y'],
            child: InkWell(
              onTap: () {
                // When the user taps on the rectangle, it will disappear
                setState(() {
                  _isRectangleVisible = false;
                });
              },
              child: Container(
                width: _position['w'],
                height: _position['h'],
                decoration: BoxDecoration(
                  border: Border.all(
                    width: 2,
                    color: Colors.blue,
                  ),
                ),
                child: Align(
                  alignment: Alignment.topLeft,
                  child: Container(
                    color: Colors.blue,
                    child: Text(
                      'hourse -71%',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                ),
              ),
            ),
          ),
      ],
    );
  }
}
Share:
1,991
Duke Le
Author by

Duke Le

Updated on December 26, 2022

Comments

  • Duke Le
    Duke Le over 1 year

    I'm using camera plug-in to get the camera feed. Every 10 seconds, I generate 4 values (x,y,w,h) and draw a rectangle (only the border, the inside is transparent) on the screen (with random text). If the user clicks on this box, it disappears.

    It looks something like this image. (x,y,w,h) and the text are randomly generated.

    enter image description here

    Is this possible to do this using camera plugin? Or is there another package that already does this?

    • dshukertjr
      dshukertjr over 3 years
      Camera plugin does not have this feature. You would have to custom build this.
    • Duke Le
      Duke Le over 3 years
      So the plugin doesn't have pressable rectangle. But does it have built-in function to draw a rectangle?
    • dshukertjr
      dshukertjr over 3 years
      Camera plugin does not have feature to draw a rectangle, but you could wrap your camera output with Stack widget and draw the bounding box with it. I could write you a sample code if that would be helpful.
    • Duke Le
      Duke Le over 3 years
      @dshukertjr Yes please! A sample code would be very helpful. If possible, adding a text on top of that rectangle (or inside the rectangle, like the above image) is also helpful
  • Duke Le
    Duke Le over 3 years
    I get "NoSuchMethodError: The getter 'value' was called on null" . My main() is just "WidgetsFlutterBinding.ensureInitialized(); runApp(new CameraApp());" Maybe something is missing?
  • dshukertjr
    dshukertjr over 3 years
    @DukeLe I just edited my answer a bit, but there maybe some small errors. What I want you to get out of this code is the basic idea of how to use Stack widget to draw over camera preview.