相机拍照后预览照片

时间:2021-04-03 00:44:02

标签: flutter

当用户拍摄照片时,我想将其发送到 photo_preview 屏幕,让用户有机会拍摄另一张照片。

本页面如下:

import 'package:flutter/material.dart';
import 'dart:io';

class photo_previewScreen extends StatelessWidget {
  final String imagePath;

  const photo_previewScreen({Key key, this.imagePath}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Display the Picture')),
      body: Image.file(File(imagePath)),
    );
  }
}

在我当前的相机页面上,将照片发送到上述页面的最佳方式是什么? 当按下拍照按钮时,这就是当前发生的事情:

onPressed: () {
                _openGallery();
                Navigator.pop(context);
              },

EDIT:整页,对答案进行了编辑

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'dart:io';

import 'package:stumble/pages/PhotoPreviewScreen.dart';

class Camera extends StatefulWidget {
  Function setData;
  Camera({Key key, this.setData}) : super(key: key);

  @override
  _CameraScreenState createState() => _CameraScreenState();
}

class _CameraScreenState extends State<Camera> {
  CameraController controller;
  List cameras;
  int selectedCameraIndex;
  String imgPath;
  var image;
  takePicture;



  Future _openGallery() async {
    image = await controller.takePicture();
    if (widget.setData != null) {
      widget.setData(File(image.path));
    }
  }

  @override
  void initState() {
    super.initState();
    availableCameras().then((availableCameras) {
      cameras = availableCameras;

      if (cameras.length > 0) {
        setState(() {
          selectedCameraIndex = 0;
        });
        _initCameraController(cameras[selectedCameraIndex]).then((void v) {});
      } else {
        print('No camera available');
      }
    }).catchError((err) {
      print('Error :${err.code}Error message : ${err.message}');
    });
  }

  Future _initCameraController(CameraDescription cameraDescription) async {
    if (controller != null) {
      await controller.dispose();
    }
    controller = CameraController(cameraDescription, ResolutionPreset.high);

    controller.addListener(() {
      if (mounted) {
        setState(() {});
      }

      if (controller.value.hasError) {
        print('Camera error ${controller.value.errorDescription}');
      }
    });

    try {
      await controller.initialize();
    } on CameraException catch (e) {}
    if (mounted) {
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: SafeArea(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              Expanded(
                flex: 1,
                child: _cameraPreviewWidget(),
              ),
              Align(
                alignment: Alignment.bottomCenter,
                child: Container(
                  height: 120,
                  width: double.infinity,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[_cameraControlWidget(context), Spacer()],
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }

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

    final size = MediaQuery.of(context).size;
    final deviceRatio = size.width / size.height;
    return Stack(children: <Widget>[
      Positioned.fill(
        child: new AspectRatio(
          aspectRatio: controller.value.aspectRatio,
          child: new CameraPreview(controller),
        ),
      ),
    ]);
  }

  Widget _cameraControlWidget(context) {
    return Expanded(
      child: Align(
        alignment: Alignment.center,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          mainAxisSize: MainAxisSize.max,
          children: <Widget>[
            FloatingActionButton(
                child: Icon(
                  Icons.center_focus_strong,
                  size: 39,
                  color: Color(0xffffffff),
                ),
                backgroundColor: Color(0xff33333D),
                onPressed: () async {
                  var result = await takePicture();
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => PhotoPreviewScreen(
                        imagePath: result,
                      ),
                    ),
                  );
                })
          ],
        ),
      ),
    );
  }
}

我收到错误

'The method 'takePicture isn't defined for the type '_CameraScreenState' 

尽管 takePicture();被定义。

1 个答案:

答案 0 :(得分:1)

您可以通过单击拍照按钮导航到预览屏幕,传递图像路径:

void onTakePictureButtonPressed() async {
  var result = await takePicture();
  Navigator.push(
    context,
    MaterialPageRoute(
      builder: (context) => PhotoPreviewScreen(
        imagePath: result,
      ),
    ),
  );
}

Future<String> takePicture() async {
    if (!controller.value.isInitialized) {
      showErrorFlushbar(context, 'Error: select a camera first.');
      return null;
    }
    final Directory extDir = await getApplicationDocumentsDirectory();
    final String dirPath = '${extDir.path}/Pictures/ompariwar';
    await Directory(dirPath).create(recursive: true);
    final String filePath = '$dirPath/${timestamp()}.jpg';

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

    try {
      await controller.takePicture(filePath);
    } on CameraException catch (e) {
      print(e);
      return null;
    }
    return filePath;
  }

在预览屏幕中,您可以这样做:

class PhotoPreviewScreen extends StatelessWidget {
  final String imagePath;

  const PhotoPreviewScreen({Key key, this.imagePath}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () => Navigator.pop(context), // Go back to the camera to take the picture again
        child: Icon(Icons.camera_alt),
      ),
      appBar: AppBar(title: Text('Display the Picture')),
      body: Column(
        children: [
          Expanded(child: Image.file(File(imagePath))),
          SomeButton(), // Add a button to send the image to server or go back to home screen here
        ],
      ),
    );
  }
}

顺便说一句,以大写字母命名您的类/小部件名称是一种约定。阅读有关此 Dart style guide 的更多信息以获得干净的代码。