Reputation: 45
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.
Upvotes: 1
Views: 2937
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