如何通过相机单击图像并设置为抖动查看图像

时间:2019-12-30 09:23:41

标签: android flutter

我正在开发一个Flutter应用程序,其中的屏幕上包含一些文本字段和imageview
我必须通过摄像头单击图像,然后显示到imageview 我已经输入了相机的基本代码,但单击按钮后无法打开相机

我已使用以下代码实现相同的

   class Survey extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return SurveyState();
  }
}

class SurveyState extends State<Survey> {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new MaterialApp(
        debugShowCheckedModeBanner: false,
        home: new Scaffold(
          appBar: AppBar(
            actions: <Widget>[
              new Padding(padding: new EdgeInsets.fromLTRB(10, 0, 0, 0)),
              RaisedButton.icon(
                textColor: Colors.white,
                onPressed: () {},
                label: Text("Fetch data"),
                color: Colors.blue,
                icon: new Image.asset(
                  'images/fetch.png',
                  width: 20,
                  height: 20,
                ),
              ),
              Spacer(),
              RaisedButton.icon(
                textColor: Colors.white,
                onPressed: () {},
                label: Text("Sync"),
                color: Colors.blue,
                icon: new Image.asset(
                  'images/sync.png',
                  width: 20,
                  height: 20,
                ),
              ),
              new Padding(padding: new EdgeInsets.fromLTRB(0, 0, 10, 0)),
            ],
          ),
          body: new SurveyForm(),
        ));
  }
}

class SurveyForm extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new SurveyFormState();
  }
}

class SurveyFormState extends State<SurveyForm> {
  TextEditingController feederName = new TextEditingController();
  TextEditingController poleType = new TextEditingController();
  CameraController controller;
  double _animatedHeight = 0.0;String _errorMsg = '';

  // Add two variables to the state class to store the CameraController and
  // the Future.

  Future<void> _initializeControllerFuture;
  String imagePath;
  var cameras;
  var selectedCameraIdx;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    // To display the current output from the camera,
    // create a CameraController.
    initCamera();
  }

  @override
  void dispose() {
    // Dispose of the controller when the widget is disposed.
    controller.dispose();
    super.dispose();
  }
  void initCamera() async {
   final camerasList = await availableCameras();
    controller = new CameraController(camerasList[0], ResolutionPreset.medium);
    await controller.initialize();
    if (mounted) {
      setState(() {});
    }
  }


  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Container(
      margin: const EdgeInsets.all(20.0),
      child: new Column(
        children: <Widget>[
          new Padding(padding: new EdgeInsets.fromLTRB(0, 20, 0, 0)),
          SizedBox(
              width: 200.0,
              height: 45.0,
              child: RaisedButton.icon(
                textColor: Colors.white,
                onPressed: () {},
                label: Text("New pole survey"),
                color: Colors.blue,
                icon: new Image.asset(
                  'images/sync.png',
                  width: 20,
                  height: 20,
                ),
              )),
          new Padding(padding: new EdgeInsets.fromLTRB(0, 10, 0, 0)),
          new TextField(
            controller: feederName,
            obscureText: true,
            decoration: new InputDecoration(
              hintText: "",
              border:
              OutlineInputBorder(borderRadius: BorderRadius.circular(5.0)),
            ),
          ),
          new Padding(padding: new EdgeInsets.fromLTRB(0, 10, 0, 0)),
          new TextField(
            controller: poleType,
            decoration: new InputDecoration(
              hintText: "",
              border:
              OutlineInputBorder(borderRadius: BorderRadius.circular(5.0)),
            ),
          ),
          new Padding(padding: new EdgeInsets.fromLTRB(0, 10, 0, 0)),
          new TextField(
            controller: poleType,
            decoration: new InputDecoration(
              hintText: "",
              border:
              OutlineInputBorder(borderRadius: BorderRadius.circular(5.0)),
            ),
          ),
          new Padding(padding: new EdgeInsets.fromLTRB(0, 10, 0, 0)),

          new Container(
            width: double.infinity,
            height: 150.0,
          // here I want to display the clicked image
          ),

          new Padding(padding: new EdgeInsets.fromLTRB(0, 10, 0, 0)),
          SizedBox(
              width: 200.0,
              height: 45.0,
              child:

              new RaisedButton.icon(
                textColor: Colors.white,

                onPressed: () async {

                  takePicture();
                },
                label: Text("Click picture"),
                color: Colors.blue,
                icon: new Image.asset(
                  'images/sync.png',
                  width: 20,
                  height: 20,
                ),
              )),

        ],
      ),
    );
  }

  /// Display Camera preview.
  Widget _cameraPreviewWidget() {
    if (controller == null || !controller.value.isInitialized) {
      return const Text(
        'Loading',
        style: TextStyle(
          color: Colors.white,
          fontSize: 20.0,
          fontWeight: FontWeight.w900,
        ),
      );
    }

    return AspectRatio(
      aspectRatio: controller.value.aspectRatio,
      child: CameraPreview(controller),
    );
  }

  void showInSnackBar(String message) {
    setState(() {
      _animatedHeight = 30.0;
      _errorMsg = message;
    });

    Future<void>.delayed(const Duration(seconds: 1), _hideErrorMsg);
  }

  void _hideErrorMsg() {
    setState(() {
      _animatedHeight = 0.0;
      _errorMsg = '';
    });
  }


  Future<String> takePicture() async {
    if (!controller.value.isInitialized) {
      showInSnackBar('Error: select a camera first.');
      return null;
    }
    final String filePath = join(
      // Store the picture in the temp directory.
      // Find the temp directory using the `path_provider` plugin.
      (await getTemporaryDirectory()).path,
      '${DateTime.now()}.png',
    );

    if (controller.value.isTakingPicture) {
      // A capture is already pending, do nothing.
      return null;
    }

    try {
      await controller.takePicture(filePath);
    } on CameraException catch (e) {
      print('Exception -> $e');
      return null;
    }
    setState(() {

    });
    return filePath;
  }
}



有人可以帮我实现相同的

2 个答案:

答案 0 :(得分:0)

首次初始化相机

CameraController _controller;
Future<void> _initializeControllerFuture;
isCameraReady = false;
showCapturedPhoto = false;
var ImagePath;

@override
void initState() {
  super.initState();
  _initializeCamera(); 

}
Future<void> _initializeCamera() async {
  final cameras = await availableCameras();
  final firstCamera = cameras.first;
  _controller = CameraController(firstCamera,ResolutionPreset.high);
  _initializeControllerFuture = _controller.initialize();
  if (!mounted) {
    return;
  }
  setState(() {
    isCameraReady = true;
  });
}

使用相机包中的CameraPreview小部件来显示相机供稿的预览。

final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height
FutureBuilder<void>(
  future: _initializeControllerFuture,
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.done) {
      // If the Future is complete, display the preview.
      return Transform.scale(
          scale: _controller.value.aspectRatio / deviceRatio,
          child: Center(
            child: AspectRatio(
              aspectRatio: _controller.value.aspectRatio,
              child: CameraPreview(_controller), //cameraPreview
            ),
          ));
    } else {
      return Center(
          child:
              CircularProgressIndicator()); // Otherwise, display a loading indicator.
    }
  },
),

创建一个在用户点击onCaptureButtonPressed()方法调用时使用CameraController拍摄图片的Button,

void onCaptureButtonPressed() async {  //on camera button press
  try {

    final path = join(
      (await getTemporaryDirectory()).path, //Temporary path
      '$pageStatus${DateTime.now()}.png',
    );
ImagePath = path;
await _controller.takePicture(path); //take photo

    setState(() {
      showCapturedPhoto = true;
    });
  } catch (e) {
    print(e);
  }
}

使用“图像”小部件显示拍摄的照片

Center(child: Image.file(File(ImagePath)));

最后不要忘记配置相机_controller

@override
void dispose() {
  // TODO: implement dispose
  _controller?.dispose();
  super.dispose();
}

有关详细说明,请访问以下链接:https://medium.com/@navinkumar0118/take-a-picture-using-flutter-camera-a9c11d282632

答案 1 :(得分:0)

只需在捕获的Image上设置一个boolean showCapturedPhoto = true并更新ImagePath。

       showCapturedPhoto ? Container(
          width: double.infinity,
          height: 150.0,
          child: Image.file(File(ImagePath)))
          : Container(),