I’m using the Camera package for flutter.
My client has a Samsung S53 phone and when it take a picture in portrait mode, the image is rotated by 90°. I tried on my Oppo A73, but no matter the orientation of my device when I take the picture, the exif orientation always returns 0 (portrait) so I don’t know whether or not the image is rotated and if I have to apply any rotation. Is this a bug with the camera plugin or something Android related? Even the width and height are always the same, so I can’t understand if the phone was in portrait or landscape mode.
This is the code:
import 'package:fatamtam/presentation/utils/scaffold_messenger_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
import 'package:permission_handler/permission_handler.dart';
class TakePicturePage extends StatefulWidget {
const TakePicturePage({
super.key,
});
static String routePath = '/take-picture';
@override
TakePictureScreenState createState() => TakePictureScreenState();
}
class TakePictureScreenState extends State<TakePicturePage> {
CameraController? _controller;
Future<void>? _initializeControllerFuture;
@override
void initState() {
super.initState();
initializeCamera();
}
void initializeCamera() async {
var permissionResult = await Permission.camera.request();
if(permissionResult.isDenied || permissionResult.isPermanentlyDenied) {
if(mounted) {
showScaffoldMessenger(context,
permissionResult.isPermanentlyDenied ? "Il permesso è stato permanentemente negato. Abilitalo dalle impostazioni del tuo telefono." : "È necessario fornire i permessi per accedere alla fotocamera.");
context.pop(null);
}
return;
}
final cameras = await availableCameras();
_controller = CameraController(cameras.first, ResolutionPreset.high,
enableAudio: false);
print(_controller);
_initializeControllerFuture = _controller?.initialize();
setState(() {});
}
@override
void dispose() {
_controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Scatta immagine')),
body: FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
_controller != null) {
// If the Future is complete, display the preview.
final scale = 1 /
(_controller!.value.aspectRatio *
MediaQuery.of(context).size.aspectRatio);
return Transform.scale(
scale: scale,
alignment: Alignment.topCenter,
child: CameraPreview(_controller!),
);
} else {
return const Center(child: CircularProgressIndicator());
}
},
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
try {
// Ensure that the camera is initialized.
await _initializeControllerFuture;
// Attempt to take a picture and get the file `image`
// where it was saved.
final image = await _controller?.takePicture();
if (!context.mounted) return;
fixImageRotation(image?.path);
// If the picture was taken, display it on a new screen.
context.pop(image?.path);
} catch (e) {
print(e);
}
},
child: const Icon(Icons.camera_alt),
),
);
}
void fixImageRotation(String? path) async {
}
}
This is what I tried to read the exif data. Image Orientation is always 0 on my phone.
Any suggestion?
final bytes = await File(imagePath).readAsBytes();
final data = await readExifFromBytes(bytes);
print(await getApplicationDocumentsDirectory());
print(await getApplicationCacheDirectory());
if (data.isEmpty || !data.containsKey('Image Orientation')) {
return imagePath;
}
img.Image? image = img.decodeImage(bytes);
if (image == null) return imagePath;