Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Camera Preview not rotating with phone orientation

I'm new to Dart/Flutter and currently using the Flutter Camera Plugin but I am running into a problem with the CameraPreview for when the phone turns to landscape mode. The images stay vertical and don't rotate the 90degrees with the phone.

I have tried countless things including Transform.rotate(), but I can't seem to get the image to both, fill the screen and rotate 90degrees.

The pictures that were taken while the phone was sideways still saved in the correct orientation when I view them, but using the _cameraPreviewWidget.

Normal

Landscape

like image 689
Matt Goodis Avatar asked May 31 '18 22:05

Matt Goodis


People also ask

How do I change camera preview orientation on android?

To force portrait orientation: set android:screenOrientation="portrait" in your AndroidManifest. xml and call camera. setDisplayOrientation(90); before calling camera.

How do you flip the camera on Flutter?

Flip camera toggle To toggle between the front and rear cameras, you have to reinitialize the camera by providing the new value to the onNewCameraSelected() method. Define a Boolean variable to understand whether the rear camera is selected, otherwise the front camera is selected.


2 Answers

My solution; using with this libraries; https://pub.dev/packages/image and https://pub.dev/packages/native_device_orientation

 Future<void> takeAPicture()async{
pictureShooting=true;
final XFile image=await cameraController!.takePicture();
img.Image? _capturedImage=img.decodeImage(await image.readAsBytes());

final NativeDeviceOrientation currentOrientation=await _nativeDeviceOrientationCommunicator.orientation(useSensor: true);

switch(currentOrientation){
  case NativeDeviceOrientation.landscapeRight: _capturedImage=img.copyRotate(_capturedImage!, 90);break;
  case NativeDeviceOrientation.landscapeLeft:   _capturedImage=img.copyRotate(_capturedImage!, 270);break;
  case NativeDeviceOrientation.portraitDown:   _capturedImage=img.copyRotate(_capturedImage!, 180);break;
  default:
}

takenImage=Uint8List.fromList(img.encodePng(_capturedImage!));

pictureShooting=false;
showImageApprovalScreen=true;

}

like image 64
leylekseven Avatar answered Sep 19 '22 18:09

leylekseven


A package call camera_camera https://pub.dev/packages/camera_camera
has do great work and provide great feature you can reference his source code or fork directly.

about rotate issue, please use this package https://pub.dev/packages/native_device_orientation
and wrap body like this

return Scaffold(
      body: NativeDeviceOrientationReader(builder: (context) {
        NativeDeviceOrientation orientation =
            NativeDeviceOrientationReader.orientation(context);

you can reference full code at https://github.com/marslord/camera/blob/master/lib/cam.dart ,this is not camera_camera package and author use RotateBox

return RotatedBox(
          quarterTurns: turns,
          child: Transform.scale(
            scale: 1 / controller.value.aspectRatio,
            child: Center(
              child: AspectRatio(
                aspectRatio: controller.value.aspectRatio,
                child: CameraPreview(controller),
              ),
            ),
          ),
        );

camera_camera package use this at line 76

return NativeDeviceOrientationReader(
  useSensor: true,
  builder: (context) {
    NativeDeviceOrientation orientation =
        NativeDeviceOrientationReader.orientation(context);

about fit screen issue
camera_camera package do this with below code full code is here https://github.com/gabuldev/camera_camera/blob/master/lib/page/camera.dart

    return widget.mode ==
              CameraMode.fullscreen
          ? OverflowBox(
              maxHeight: size.height,
              maxWidth: size.height *
                  previewRatio,
              child: CameraPreview(
                  bloc.controllCamera),
            )
          : AspectRatio(
              aspectRatio: bloc
                  .controllCamera
                  .value
                  .aspectRatio,
              child: CameraPreview(
                  bloc.controllCamera),
            );

execute result of camera_camera package can found on his github

execute result of https://github.com/marslord/camera
enter image description here

both check with real device and works

official camera plugin example rotate image can work with combine Native_device_orientation and RotateBox , you can reference https://github.com/marslord/camera/blob/master/lib/cam.dart
but official camera plugin example fit screen issue will need to modify layout code

I would suggest use camera_camera's method, Stack CameraPreview and Button. it looks more like Native Camera App and easy to maintain landscape mode

official camera plugin example rotate image code snippet with combine Native_device_orientation and RotateBox

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        title: const Text('Camera example'),
      ),
      body: NativeDeviceOrientationReader(builder: (context) {

        NativeDeviceOrientation orientation =
        NativeDeviceOrientationReader.orientation(context);

        int turns;
        switch (orientation) {
          case NativeDeviceOrientation.landscapeLeft:
            turns = -1;
            break;
          case NativeDeviceOrientation.landscapeRight:
            turns = 1;
            break;
          case NativeDeviceOrientation.portraitDown:
            turns = 2;
            break;
          default:
            turns = 0;
            break;
        }

        return Column(
          children: <Widget>[
            Expanded(
              child: RotatedBox(
                quarterTurns: turns,
                child: Transform.scale(
                  scale: 1 / controller.value.aspectRatio,
                  child: Container(
                    child: Padding(
                      padding: const EdgeInsets.all(1.0),
                      child: AspectRatio(
                        aspectRatio: controller.value.aspectRatio,
                        child: Center(
                          child: _cameraPreviewWidget(),
                        ),
                      ),
                    ),
like image 26
chunhunghan Avatar answered Sep 22 '22 18:09

chunhunghan