Flutter 如何在相机进给上绘制可按下的矩形?

Flutter how to draw pressable rectangle on camera feed?

我正在使用 camera 插件获取摄像头画面。每 10 秒,我生成 4 个值 (x,y,w,h) 并在屏幕上绘制一个矩形(只有边框,内部是透明的)(带有随机文本)。如果用户单击此框,它就会消失。

看起来像这张图片。 (x,y,w,h) 并且文字是随机生成的。

是否可以使用 camera 插件来做到这一点?或者是否有另一个软件包已经这样做了?

Camera 插件没有任何绘制预览的功能,但您可以使用 Stack 小部件和容器制作类似的东西。

这是一个简单粗暴的例子,但希望能给您一些启发:

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),
                    ),
                  ),
                ),
              ),
            ),
          ),
      ],
    );
  }
}