使用官方flutter相机插件时如何水平翻转原始相机图像?

Ann*_*ess 1 camera flutter flutter-web

我目前正在开发一个 flutter web 应用程序,用户应该能够预览相机并手动保存图片。因此我使用官方的相机插件。我能够初始化相机、预览内容并在按下按钮时保存图片。

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"),
            ),
          ],
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是相机内容(图像)方向错误。

显示预览和旋转的存储图像

该图片显示顶部的预览和下方的翻转存储图像。

我可以保存图片并随后旋转它。但我想当图像来自流时直接翻转图像。所以预览显示正确。

有没有办法做到这一点,而不需要编辑插件?也许有翻转或镜像选项。

Ann*_*ess 5

感谢 justAsascha,我找到了一个解决方案或解决方法,它可以转换(翻转)CameraPreview,使其与存储的图像方向相同。

只需使用变换包装 CameraPreview 小部件并将 y 轴旋转 pi 即可。此解决方案需要 dart:math 导入,用于 math.pi。

import 'dart:math' as math;

...

Transform(
    alignment: Alignment.center,
    transform: Matrix4.rotationY(math.pi),
    child: CameraPreview(controller),
),

...

Run Code Online (Sandbox Code Playgroud)

也许有一个更好的解决方案,然后转换预览并转换存储的图像。