Anneress
Anneress

Reputation: 389

How to flip the raw camera image horizontally, when using official flutter camera plugin?

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.

shows the preview and rotated stored image

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

Answers (1)

Anneress
Anneress

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

Related Questions