Reputation: 389
I am currently developing a flutter webapp, where the user should be able to preview the camera and manually save a picture. Therefore I use the official camera plugin. I am able to initialize the camera, preview the content and save a picture on button press.
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:image/image.dart' as img;
late List<CameraDescription> _cameras;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
_cameras = await availableCameras();
runApp(const CameraApp());
}
class CameraApp extends StatefulWidget {
const CameraApp({Key? key}) : super(key: key);
@override
State<CameraApp> createState() => _CameraAppState();
}
class _CameraAppState extends State<CameraApp> {
late CameraController controller;
Image? image;
@override
void initState() {
super.initState();
// define and initialize the camera controller once
controller = CameraController(
_cameras[0],
ResolutionPreset.max,
imageFormatGroup: ImageFormatGroup.jpeg,
);
controller.initialize().then((_) {
if (!mounted) {
return;
}
setState(() {});
}).catchError((Object e) {
if (e is CameraException) {
switch (e.code) {
case 'CameraAccessDenied':
print('User denied camera access.');
break;
default:
print('Handle other errors.');
break;
}
}
});
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (!controller.value.isInitialized) {
return Container();
}
return MaterialApp(
home: Scaffold(
body: ListView(
children: [
CameraPreview(controller), // shows preview
if (image != null) image!,
ElevatedButton(
onPressed: () async {
// take picture
try {
final XFile file = await controller.takePicture();
// load the picture as bytes
final blob = await file.readAsBytes();
// try to flip it horizontally
final img.Image? original = img.decodeImage(blob);
if (original != null) {
final img.Image oriented = img.flipHorizontal(original);
final orientedBlob =
Uint8List.fromList(img.encodeJpg(oriented));
setState(() {
// set the image to show the output
image = Image.memory(orientedBlob);
});
}
} catch (e) {
print(e);
}
},
child: const Text("Digitalisieren"),
),
],
),
),
);
}
}
The problem I have, is that the camera content (images) are in the wrong direction.
The picture shows the preview on top and the flipped stored image below that.
I can save a picture and rotate it afterwards. But I would like to flip the image directly when it comes from the stream. So the preview displays it correctly.
Is there a way to do that, without editing the plugin? Maybe there is a flip or mirror option.
Upvotes: 2
Views: 3171
Reputation: 389
Thanks to justAsascha I found a solution or workaround, which transforms (flips) the CameraPreview, so that it is in the same direction as the stored image.
Just wrap the CameraPreview widget with a transform and rotate the y-axis by pi. This solution needs dart:math import, for the math.pi.
import 'dart:math' as math;
...
Transform(
alignment: Alignment.center,
transform: Matrix4.rotationY(math.pi),
child: CameraPreview(controller),
),
...
Maybe there is a better solution then transforming the preview and also transforming the stored image.
Upvotes: 7