Reputation: 2486
I have an app where I have a Scaffold
with an AppBar
and a bottom Ads Banner.
In between, there is the CameraPreview
from the camera plugin in Flutter.
As the CameraPreview
is made to take the aspect ratio of the device/camera, the CameraPreview
doesn't take the entire available space, leaving extra space on most devices.
I tried to crop the CameraPreview
to show only whatever fits in the available space. It worked, but now the preview is stretched out
LayoutBuilder(
builder: (context, constraints) {
final cameraController = controller.cameraController!;
if(cameraController.value.previewSize != null) {
return ClipRect(
child: OverflowBox(
alignment: Alignment.center,
child: FittedBox(
fit: BoxFit.fitWidth,
child: SizedBox(
width: constraints.maxWidth,
height: constraints.maxWidth,
child: AspectRatio(
aspectRatio: cameraController.value.aspectRatio,
child: CameraPreview(cameraController),
),
),
),
),
);
} else {
return const SizedBox.shrink();
}
},
)
I tried other solutions like Transform.scale
, but that only zooms into the preview, it doesn't change the ratio or the stretching.
Looking solutions in the package itself doesn't help either, most similar issues are stalling or already closed for stalling.
What am I supposed to do here? Am I supposed to manually clip the preview's value?
Upvotes: 2
Views: 2697
Reputation: 1957
check this below code,
Use get screen size by MediaQuery & calculate scale for aspect ratio widget and add CameraPreview() to it like below
// get screen size
final size = MediaQuery.of(context).size;
// calculate scale for aspect ratio widget
var scale = cameraController.value.aspectRatio / size.aspectRatio;
// check if adjustments are needed...
if (cameraController.value.aspectRatio < size.aspectRatio) {
scale = 1 / scale;
}
return Transform.scale(
scale: scale,
child: Center(
child: AspectRatio(
aspectRatio: cameraController.value.aspectRatio,
child: CameraPreview(cameraController),
),
),
);
Complete code
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
if (controller != null && controller.value.isRecordingVideo) {
//stop video
}
},
child: Scaffold(
resizeToAvoidBottomInset: false,
key: _scaffoldKey,
body: Container(
child: Stack(
children: [
Positioned(
child: Container(
alignment: Alignment.center,
child: cameraScreen(),
),
),
Positioned(
child: Container(
alignment: Alignment.bottomCenter,
child: Container(
height: MediaQuery.of(context).size.height * .1,
color: Colors.black54,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
//can add Controls
],
),
),
),
)
],
),
),
),
);
}
Widget cameraScreen() {
final CameraController cameraController = controller;
if (cameraController == null || !cameraController.value.isInitialized) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.black,
child: Center(
child: Text(
"Loading Camera...",
style: CameraTextStyle.cameraUtilLoadingStyle(),
),
),
);
} else {
return cameraWidget(context, cameraController);
}
}
Widget cameraWidget(context, cameraController) {
// get screen size
final size = MediaQuery.of(context).size;
// calculate scale for aspect ratio widget
var scale = cameraController.value.aspectRatio / size.aspectRatio;
// check if adjustments are needed...
if (cameraController.value.aspectRatio < size.aspectRatio) {
scale = 1 / scale;
}
return Transform.scale(
scale: scale,
child: Center(
child: AspectRatio(
aspectRatio: cameraController.value.aspectRatio,
child: CameraPreview(cameraController),
),
),
);
}
Widget cameraSwitch() {
final CameraController cameraController = controller;
return Container(
child: InkWell(
onTap: () {
if (cameraController != null &&
cameraController.value.isInitialized &&
!cameraController.value.isRecordingVideo) {
if (cameras.isNotEmpty) {
if (selectedCamera == cameras[0]) {
selectedCamera = cameras[1];
onNewCameraSelected(selectedCamera);
} else {
selectedCamera = cameras[0];
onNewCameraSelected(selectedCamera);
}
}
}
setState(() {});
},
child: Icon(
Icons.switch_camera,
size: 30,
color: Colors.white,
),
),
);
}
Upvotes: 1