Camera preview not matching device | flutter - flutter

My camera preview is distorted. It appears far too zoomed in, and also stretched.
What am I doing wrong? How can I fix?
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),
),
),
),
]);
}
Note: Should work for iOS and Android.
I am using camera package: camera: ^0.7.0+2
Here full page
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'dart:io';
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();
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: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
flex: 1,
child: _cameraPreviewWidget(),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 120,
width: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[_cameraControlWidget(context), Spacer()],
),
),
)
],
),
),
),
);
}
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>[
Center(
child: Transform.scale(
scale: controller.value.aspectRatio / deviceRatio,
child: new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: new CameraPreview(controller),
),
),
),
]);
}
Widget _cameraControlWidget(context) {
return Expanded(
child: Align(
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
FloatingActionButton(
child: Icon(
Icons.camera,
color: Colors.black,
),
backgroundColor: Colors.white,
onPressed: () {
_openGallery();
Navigator.pop(context);
},
)
],
),
),
);
}
}
Edit based on answer:
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
return Stack(children: <Widget>[
Center(
child: Transform.scale(
scale: 16 / 9,
child: Center(
child: AspectRatio(
aspectRatio: 1,
child: Camera(),
),
),
),
),
]);
}

Had the same problem using camerawesome some times ago.
Had to use Transform and an Aspect Ratio:
Transform.scale(
scale: 16 / 9,
child: Center(
child: AspectRatio(
aspectRatio: 1,
child: Camera(),
),
),
),

Use Matrix4.diagonal3Values for scaling, as we can then control the X, Y, Z axis. X is the horizontal, Y is the vertical and Z is for the ones that want to go into other dimensions 🚀.
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
final xScale = cameraController.value.aspectRatio / deviceRatio;
// Modify the yScale if you are in Landscape
final yScale = 1;
return Container(
child: AspectRatio(
aspectRatio: deviceRatio,
child: Transform(
alignment: Alignment.center,
transform: Matrix4.diagonal3Values(xScale, yScale, 1),
child: CameraPreview(cameraController),
),
),
);
If you are working with a camera that rotates and supports Landscape, you will most likely need to scale up the Y axis, and skip the X.
The Lightsnap app is locked in Portrait so we don’t need to re-scale the camera preview when the phone rotates. Just a note that you may need to do this if you are supporting landscape.
Thanks to Lightsnap(More Details here)

Related

Audio composing dashboard with flutter

I m trying to create the following view on my app, other area are done but now comes to the core feature of the app, which allows people to record the audio and stack other audio on top of the one that has been recorded, before going on the hard parts of recording and margin or trim the audios, I am stuck on the view, plz anyone who can shade a light on this will be appreciated. spare the bottom navigation bar, that one has no issue, only the timeline board.
here the view that I just prototyped.
Here some code that I've tried to play with but failed.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class Studio extends StatefulWidget {
const Studio({Key? key}) : super(key: key);
#override
_Studio createState() => _Studio();
}
class _Studio extends State<Studio> with SingleTickerProviderStateMixin {
late AnimationController _controller;
double _time = 0.0, _scale = 1.0;
int _minutes = 0;
int _seconds = 0;
#override
void initState() {
super.initState();
_controller =
AnimationController(vsync: this, duration: Duration(seconds: 60));
_controller.addListener(() {
setState(() {
_time = _controller.value;
_minutes = (_time * 60).floor();
_seconds = ((_time * 60) % 1 * 60).floor();
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Timeline'),
),
body: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 12,
itemBuilder: (context, index) {
return Container(
width: 50,
height: 50,
margin: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Text('$index'),
),
);
},
),
),
Container(
padding: EdgeInsets.all(8),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('$_minutes'),
Text(':'),
Text('$_seconds'),
],
),
),
ElevatedButton(
onPressed: () {
if (_controller.isAnimating) {
_controller.stop();
} else {
_controller.forward();
}
},
child: Text(_controller.isAnimating ? 'Stop' : 'Start'),
),
],
),
);
}
void _onScaleStart(ScaleStartDetails details) {
print(details);
setState(() {
//_scale = details.focalPoint;
});
}
void _onScaleUpdate(ScaleUpdateDetails details) {
setState(() {
_scale = details.scale;
});
}
Widget _buildTimeline() {
return Container(
height: 40,
child: Row(
children: <Widget>[
_buildTimelineMinute(0),
_buildTimelineMinute(5),
_buildTimelineMinute(10),
],
),
);
}
Widget _buildTimelineHour(int hour) {
return Container(
width: 10,
color: Colors.green,
child: Center(
child: Text(
"$hour:00",
style: TextStyle(color: Colors.black, fontSize: 12),
),
),
);
}
Widget _buildTimelineMinute(int minute) {
return Container(
width: 10,
color: Colors.green,
child: Center(
child: Text(
"$minute",
style: TextStyle(color: Colors.black, fontSize: 12),
),
),
);
}
}
Thank you

Changing the CameraPreview Aspect Ratio (Flutter)

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?
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,
),
),
);
}

Making camera preview full-screen

I would like the camera preview screen to be full-screen, instead of the camera condensed down into a rectangle.
In other words, I would like the camera preview to cover the entire screen, and me build the elements on top of this. Not for the elements to reduce the camera preview.
Is there a specific element of code I need to add?
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:camera/camera.dart';
import 'dart:io';
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();
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: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
flex: 1,
child: _cameraPreviewWidget(),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 120,
width: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[_cameraControlWidget(context), Spacer()],
),
),
)
],
),
),
),
);
}
/// Display Camera preview.
Widget _cameraPreviewWidget() {
if (controller == null || !controller.value.isInitialized) {
return const Text(
'Loading',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.w900,
),
);
}
return AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: CameraPreview(controller),
);
}
/// Display the control bar with buttons to take pictures
Widget _cameraControlWidget(context) {
return Expanded(
child: Align(
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
FloatingActionButton(
child: Icon(
Icons.camera,
color: Colors.black,
),
backgroundColor: Colors.white,
onPressed: () {
// getImage();
_openGallery();
Navigator.pop(context);
},
)
],
),
),
);
}
}
The Column widget puts widgets on top of each other vertically. Instead, you should use the Stack widget:
Something like this:
return Scaffold(
body: Container(
child: SafeArea(
child: Stack(
children: [
Expanded(
flex: 1,
child: _cameraPreviewWidget(),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 120,
width: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[_cameraControlWidget(context), Spacer()],
),
),
)
],
),
),
),
);

FlatButton taking up whole screen in flutter web

I am building a webapp with flutter where I want to add google sign in. The button itself works fine, but whatever I try, it just takes up my whole screen. I tried putting the button in the class in a container and putting it in a sizedbox on the page I actually want to use it on, and limiting the size of the button itself. This is my first time with flutter web, so I'd really like to know why this is happening.
Here is my code for the button:
class GoogleButton extends StatefulWidget {
#override
_GoogleButtonState createState() => _GoogleButtonState();
final DatabaseRepo databaseRepo;
final InitRepo initRepo;
GoogleButton(this.databaseRepo, this.initRepo);
}
class _GoogleButtonState extends State<GoogleButton> {
bool _isProcessing = false;
#override
Widget build(BuildContext context) {
return SizedBox(
height: MediaQuery.of(context).size.height / 10,
child: FlatButton(
height: MediaQuery.of(context).size.height / 10,
onPressed: () async {
setState(() {
_isProcessing = true;
});
await signInWithGoogle().then((result) {
print(result);
Navigator.of(context).pop();
Navigator.of(context).push(
MaterialPageRoute(
fullscreenDialog: true,
builder: (context) =>
MainPage(widget.databaseRepo, widget.initRepo),
),
);
}).catchError((error) {
print('Registration Error: $error');
});
setState(() {
_isProcessing = false;
});
},
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 0, 10),
child: _isProcessing
? CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(
Colors.blueGrey,
),
)
: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 20),
child: Text(
'Bejelentkezés',
style: TextStyle(
fontSize: 20,
color: Colors.blueGrey,
),
))
]))),
);
}
}
Just to be on the safe side, here is the code for the page itself:
import 'package:flutter/material.dart';
import 'package:foci_dev/repo/database_repo.dart';
import 'package:foci_dev/repo/init_repo.dart';
import 'package:foci_dev/ui/google_button.dart';
class SignInPage extends StatelessWidget {
final DatabaseRepo databaseRepo;
final InitRepo initRepo;
SignInPage(this.databaseRepo, this.initRepo);
#override
Widget build(BuildContext context) {
return Container(
color: Colors.grey[800],
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 5,
width: MediaQuery.of(context).size.height / 5,
child: Column(
children: [
Image(image: AssetImage('lib/assets/icon.png')),
Container(
height: MediaQuery.of(context).size.height / 10,
child: ButtonTheme(
height: 20,
child:
GoogleButton(this.databaseRepo, this.initRepo))),
],
)),
],
),
);
}
}
Thank you very much for your help, I really don't know what to do.

AspectRatio problem with Flutter camera and image layer

I have an AspectRatio problem with my Flutter camera (Plugin "camera_camera) and an image that I put on top of it with transparency as a layer.
I send you a screenshot of the problem. In the screenshot you can see the open camera and above it the picture I took right in front of it. Unfortunately you can see at different places that it does not match.
How do I get the camera to show exactly the same proportions as I photographed it from exactly the same position before?
If this helps: I recorded also a video with the issue:
https://danielederosa.de/downloads/flutter_issue.mp4
My Code
#override
Widget build(BuildContext context) {
final theme = Theme.of(context);
if (!controller.value.isInitialized) {
return Container(
color: theme.colorScheme.onPrimary,
child: Center(child: CircularProgressIndicator()));
}
return Scaffold(
appBar: CupertinoNavigationBar(
backgroundColor: theme.colorScheme.primary,
border: Border.symmetric(
vertical: BorderSide.none, horizontal: BorderSide.none),
automaticallyImplyLeading: false,
leading: IconButton(
icon: Icon(
Icons.chevron_left,
size: 30,
color: theme.colorScheme.onPrimary,
),
onPressed: () => Navigator.pop(context),
),
middle: Text("Memories",
style: TextStyle(
color: theme.colorScheme.onPrimary,
fontSize: theme.textTheme.headline3.fontSize)),
),
body: Container(
child: Column(
children: [
Expanded(
child: Camera(
mode: CameraMode.normal,
imageMask: lastPicture != null
? new Positioned.fill(
child: new Opacity(
opacity: 0.3,
child: RotatedBox(
quarterTurns: 1,
child: new Image.file(
File(lastPicture),
fit: BoxFit.cover,
),
),
),
)
: Container(),
onFile: (File file) {
_workWithImage(file);
},
),
),
],
),
),
);
}
I also tried to wrap the Camera widget into an AspectRatio widget with aspectRatio: 3/4 because my saved image are saved in this aspectRatio. But without success.
Do you have any idea to solve this issue?
I found a solution and got it to work.
Example code
#override
Widget build(BuildContext context) {
final theme = Theme.of(context);
var deviceSize = MediaQuery.of(context).size;
var sizeWidth = MediaQuery.of(context).size.width;
final deviceRatio = deviceSize.width / deviceSize.height;
var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;
return Scaffold(
backgroundColor: theme.colorScheme.primary,
appBar: CupertinoNavigationBar(
backgroundColor: theme.colorScheme.primary,
border: Border.symmetric(
vertical: BorderSide.none, horizontal: BorderSide.none),
automaticallyImplyLeading: false,
leading: IconButton(
icon: Icon(
Icons.chevron_left,
size: 30,
color: theme.colorScheme.onPrimary,
),
onPressed: () => Navigator.pop(context),
),
middle: Text(APP_NAME,
style: TextStyle(
color: theme.colorScheme.onPrimary,
fontSize: theme.textTheme.headline3.fontSize)),
),
body: NativeDeviceOrientationReader(
useSensor: true,
builder: (context) {
NativeDeviceOrientation orientation =
NativeDeviceOrientationReader.orientation(context);
return Stack(children: [
FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the Future is complete, display the preview.
return MeasureSize(
onChange: (size) {
setState(() {
cameraSize = size;
});
},
child: Transform.scale(
scale: cameraController.value.aspectRatio / deviceRatio,
child: Center(
child: AspectRatio(
aspectRatio: cameraController.value.aspectRatio,
child: ClipRect(
child: OverflowBox(
alignment: Alignment.center,
child: FittedBox(
fit: BoxFit.fitWidth,
child: Container(
width: sizeWidth,
height: sizeWidth /
cameraController.value.aspectRatio,
child: CameraPreview(
cameraController), // this is my CameraPreview
),
),
),
),
),
),
),
);
} else {
// Otherwise, display a loading indicator.
return Center(child: CircularProgressIndicator());
}
},
),
helpMode == true
? Transform.scale(
scale: cameraController.value.aspectRatio / deviceRatio,
child: Center(
child: Opacity(
opacity: .3,
child: orientation ==
NativeDeviceOrientation.landscapeLeft ||
orientation ==
NativeDeviceOrientation.landscapeRight
? RotatedBox(
quarterTurns: orientation ==
NativeDeviceOrientation.landscapeLeft
? 1
: 3,
child: Image.file(
File(lastPicture),
height: cameraSize.width,
fit: BoxFit.contain,
))
: Image.file(
File(lastPicture),
width: cameraSize.width,
height: cameraSize.height,
fit: BoxFit.contain,
),
),
),
)
: Container(),
]);
},
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Container(
transform: Matrix4.translationValues(0.0, -8.0, 0.0),
child: FloatingActionButton(
backgroundColor: theme.colorScheme.primary,
child: Icon(
Icons.camera_alt,
color: theme.colorScheme.onPrimary,
),
// Provide an onPressed callback.
onPressed: () async {
// Take the Picture in a try / catch block. If anything goes wrong,
// catch the error.
try {
// Ensure that the camera is initialized.
//await _initializeControllerFuture;
// Construct the path where the image should be saved using the path
// package.
final path = join(
// Store the picture in the temp directory.
// Find the temp directory using the `path_provider` plugin.
(await getTemporaryDirectory()).path,
'${DateTime.now()}.png',
);
// Attempt to take a picture and log where it's been saved.
await cameraController.takePicture(path);
_workWithImage(File(path));
} catch (e) {
// If an error occurs, log the error to the console.
print(e);
}
},
),
),
);
}
}
typedef void OnWidgetSizeChange(Size size);
class MeasureSize extends StatefulWidget {
final Widget child;
final OnWidgetSizeChange onChange;
const MeasureSize({
Key key,
#required this.onChange,
#required this.child,
}) : super(key: key);
#override
_MeasureSizeState createState() => _MeasureSizeState();
}
class _MeasureSizeState extends State<MeasureSize> {
#override
Widget build(BuildContext context) {
SchedulerBinding.instance.addPostFrameCallback(postFrameCallback);
return Container(
key: widgetKey,
child: widget.child,
);
}
var widgetKey = GlobalKey();
var oldSize;
void postFrameCallback(_) {
var context = widgetKey.currentContext;
if (context == null) return;
var newSize = context.size;
if (oldSize == newSize) return;
oldSize = newSize;
widget.onChange(newSize);
}
}
I created the MeasureSize class. With this class I get the dimensions of a child widget. In this case I need the width and height from the camera. (Transform.scale) After I got this I had only to set this dimensions for the image overlay:
Image.file(
File(lastPicture),
width: cameraSize.width,
height: cameraSize.height,
fit: BoxFit.contain,
),
Now the image overlay fits to this what the camera displays.