Iam using CameraPreview for measuring height of an object,But the issue was i cant able to set cameraPreview height full screen..
I have tried Positioned widget, it fills the screen but the image was stretched. I have tried Transform Widget, but height does not fills fullscreen, white space is coming.Image is not stretched.
Mycode:
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
return Stack(
children: <Widget>[
Transform.scale(
scale: controller.value.aspectRatio/deviceRatio,
child: new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: new CameraPreview(controller),
),
),);
Kindly help me to fit CameraPreview "FULLSCREEN" without image streching..
CameraValue.aspectRatio returns width / height rather than height / width since 0.7.0, and CameraPreview handles AspectRatio itself now, so imo the working code snippet would be as follows:
/// only work inside WidgetsApp or MaterialApp, which introduces a MediaQuery
final scale = 1 / (controller.value.aspectRatio * MediaQuery.of(context).size.aspectRatio);
return Transform.scale(
scale: scale,
alignment: Alignment.topCenter,
child: CameraPreview(controller),
);
update:
After scale by Transform the preview may paint off screen-size limit when used in a TransitionRoute. (When hosted in a CupertinoPageRoute a drag gesture will clearly show this).
So I think it would be a good idea to clip the preview to make it exactly matching the screen size.
final mediaSize = MediaQuery.of(context).size;
final scale = 1 / (controller.value.aspectRatio * mediaSize.aspectRatio);
return ClipRect(
clipper: _MediaSizeClipper(mediaSize),
child: Transform.scale(
scale: scale,
alignment: Alignment.topCenter,
child: CameraPreview(controller),
),
);
class _MediaSizeClipper extends CustomClipper<Rect> {
final Size mediaSize;
const _MediaSizeClipper(this.mediaSize);
@override
Rect getClip(Size size) {
return Rect.fromLTWH(0, 0, mediaSize.width, mediaSize.height);
}
@override
bool shouldReclip(CustomClipper<Rect> oldClipper) {
return true;
}
}
Issue has been solved by wrapping Centre widget in Transform widget
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
return Stack(
children: <Widget>[
Center(
child:Transform.scale(
scale: controller.value.aspectRatio/deviceRatio,
child: new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: new CameraPreview(controller),
),
),),);
Unfortunately both Wangpan and Navin Kumar's answers did not work for me. But the following solution did work for me.
I have two state widget fields:
The cameraControllerKey
, used to make a reference to the Container holding the CameraPreview.
The cameraPreviewScale
used to store the size of the original cameraPreview.
In my build method I first let the CameraView build its UI and set the scale to 1, meaning that I just let it draw itself as it comes (so not full screen... Yet). Also note that i set the key
to my GlobalKey cameraControllerKey
.
In the addPostFrameCallback
method I calculate the scale based on the Container view size that holds the CameraPreview and the actual screenSize. I hope it helps for you, happy fluttering.
///field in widget state
var cameraControllerKey = GlobalKey();
double? cameraPreviewScale;
/// In build method
if(cameraPreviewScale==null){
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
final screenSize = MediaQuery.of(context).size;
final previewSize = cameraControllerKey.currentContext!.size!;
setState(() {
cameraPreviewScale = screenSize.width / previewSize.width;
});
});
}
return Scaffold(
key: _scaffoldKey,
body:
Stack(
fit: StackFit.loose,
children: [
Center(
child: Container(
key: cameraControllerKey,
child: Transform.scale(
alignment: Alignment.center,
scale: cameraPreviewScale ?? 1,
child: CameraPreview(cameraController!))),
),
],
)
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With