如何在颤动中修复相机照片的错误旋转?

Spr*_*owk 13 android-camera dart flutter

我正在使用最新的相机插件版本拍照,我正在使用颤振示例中的代码。这是我选择相机的方式:

final cameras = await availableCameras();
final firstCamera = cameras.first;
Run Code Online (Sandbox Code Playgroud)

这是在init里面:

_cameraController = CameraController(
  widget.camera,
  ResolutionPreset.medium,
  enableAudio: false,
);
Run Code Online (Sandbox Code Playgroud)

这是相关代码的其余部分:

Future _takePhoto(BuildContext context) async {
  try {
    await _initializeControllerFuture;
    final path = join(
      (await getTemporaryDirectory()).path,
      '${DateTime.now()}.png',
    );

    await _cameraController.takePicture(path);

    setState(() {
      _imagePath = path;
    });
  } catch (e) {
    print(e);
  }
}
Run Code Online (Sandbox Code Playgroud)

之后,我将照片展示给用户,Image.file(File(_imagePath))然后将照片发送到 API。问题是有时会以错误的方向拍摄照片。(这个我很确定,因为照片在数据库中也旋转了。)例如,在3年前的小米手机上,它完美无缺,但在某些新的三星手机上,照片总是旋转。

如何确保旋转始终正确?(即使在 ios 设备上)

小智 27

这对我有用:

import 'package:image/image.dart' as img;

...

final img.Image capturedImage = img.decodeImage(await File(path).readAsBytes());
final img.Image orientedImage = img.bakeOrientation(capturedImage);
await File(path).writeAsBytes(img.encodeJpg(orientedImage));
Run Code Online (Sandbox Code Playgroud)

  • 这对我来说很有用,因为我已经在使用图像插件了,谢谢!太糟糕了,本来就很慢的图像捕获变得更慢、更糟糕,为什么在两年多后,如此严重的错误仍然存​​在于颤振中 (2认同)

Dom*_*ski 11

这是我的跨平台解决方案,不使用插件。

import 'dart:io';
import 'package:exif/exif.dart';
import 'package:image/image.dart' as img;

Future<File> fixExifRotation(String imagePath) async {
    final originalFile = File(imagePath);
    List<int> imageBytes = await originalFile.readAsBytes();

    final originalImage = img.decodeImage(imageBytes);

    final height = originalImage.height;
    final width = originalImage.width;

    // Let's check for the image size
    // This will be true also for upside-down photos but it's ok for me
    if (height >= width) {
      // I'm interested in portrait photos so
      // I'll just return here
      return originalFile;
    }

    // We'll use the exif package to read exif data
    // This is map of several exif properties
    // Let's check 'Image Orientation'
    final exifData = await readExifFromBytes(imageBytes);

    img.Image fixedImage;

    if (height < width) {
      logger.logInfo('Rotating image necessary');
      // rotate
      if (exifData['Image Orientation'].printable.contains('Horizontal')) {
        fixedImage = img.copyRotate(originalImage, 90);
      } else if (exifData['Image Orientation'].printable.contains('180')) {
        fixedImage = img.copyRotate(originalImage, -90);
      } else if (exifData['Image Orientation'].printable.contains('CCW')) {
        fixedImage = img.copyRotate(originalImage, 180);
      } else {
        fixedImage = img.copyRotate(originalImage, 0);
      }
    }

    // Here you can select whether you'd like to save it as png
    // or jpg with some compression
    // I choose jpg with 100% quality
    final fixedFile =
        await originalFile.writeAsBytes(img.encodeJpg(fixedImage));

    return fixedFile;
  }
Run Code Online (Sandbox Code Playgroud)

来源

  • 这是一个可接受的解决方案@DominikRoszkowski,但理想情况下,应该纠正并写出 exif 方向元数据,而不是实际修改底层图像数据的旋转,这不一定是无损操作。 (2认同)

chu*_*han 4

您可以使用包https://pub.dev/packages/flutter_exif_rotation
支持iOS,并且Android
在某些设备中,exif 数据以横向模式显示图片,而实际上它们是纵向的。
该插件修复了使用这些设备拍摄的照片的方向。

对于 Android
将其添加到您的AndroidManifest.xml

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Run Code Online (Sandbox Code Playgroud)

代码片段

image = await FlutterExifRotation.rotateImage(path: image.path);

//Note : iOS not implemented
image = await FlutterExifRotation.rotateAndSaveImage(path: image.path);
Run Code Online (Sandbox Code Playgroud)

  • 刚刚在有问题的设备上尝试过,它仍然在旋转照片。 (3认同)