S Tyler
S Tyler

Reputation: 45

Camera preview stretched vertically

My camera preview is currently stretched vertically as per the screenshot attached.

The code to the camera page is below, does anyone know how to adjust the code so that the camera preview does not appear to be stretched?

I need it to work for iOS and Android, and for every device.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'dart:io';
import 'package:flutter/services.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;

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

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

    SystemChrome.setEnabledSystemUIOverlays([]);

    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: Stack(
          children: <Widget>[
            _cameraPreviewWidget(),
            _cameraControlWidget(context)
          ],
        ),
      ),
    );
  }

  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 Container(
        child: Align(
            alignment: Alignment.center,
            child: FloatingActionButton(
              child: Icon(
                Icons.center_focus_strong,
                size: 39,
                color: Color(0xd),
              ),
              backgroundColor: Color(0xff33333D),
              onPressed: () {
                _openGallery();
                Navigator.pop(context);
              },
            )
            ));
  }
}

and here is the image as to how it is rendering. The button in the middle takes the photo.

enter image description here

Upvotes: 1

Views: 2937

Answers (1)

dshukertjr
dshukertjr

Reputation: 18690

I have struggled with the camera preview in Flutter as well. It is a pain to work with. This is what I am using right now. Hopefully it will help you

class CameraPreview extends StatelessWidget {
  const CameraPreview({Key? key, this._cameraController}) : super(key: key);

  final CameraController _cameraController;

  @override
  Widget build(BuildContext context) {
    return ClipRect(
      child: OverflowBox(
        alignment: Alignment.center,
        child: FittedBox(
          fit: BoxFit.cover,
          child: SizedBox(
            height: 1,
            child: AspectRatio(
              aspectRatio: 1 / _cameraController.value.aspectRatio,
              child: CameraPreview(_cameraCcontroller),
            ),
          ),
        ),
      ),
    );
  }
}

Upvotes: 12

Related Questions