Handling Image Orientation and Freezing Issues with Flutter on iOS

24 Views Asked by At

I'm developing a mobile app using Flutter and have encountered an issue where some images uploaded by users are displayed with incorrect orientation. This problem seems to occur only with images from iPhones, specifically those taken with the Live Photo feature. It appears that Flutter struggles to correctly process the orientation of these photos.

To address this, I've tried using the flutter_exif_rotation package (version 0.5.1) as follows:

File file = await FlutterExifRotation.rotateImage(path: pickedFile.path);

Additionally, to further mitigate the issue, I've implemented image quality adjustment like this:

final bytes = await File(file.path).readAsBytes();
final img.Image? image = img.decodeImage(bytes);
if (image != null) {
  final img.Image orientedImage = img.bakeOrientation(image);
  await File(file.path)
      .writeAsBytes(img.encodeJpg(orientedImage, quality: 90));
}

These solutions have effectively resolved the orientation issue. However, a new problem has emerged: when processing high-quality images, there's a noticeable freeze, which I believe is due to the processing happening on the main thread. I've considered running the processing in a separate isolate, but isolates don't seem to have access to the main memory, and I'm unsure how to implement this solution.

link to a video demonstrating the freezing issue: https://disk.yandex.ru/i/ki05_HNKe2X2lw

Question: How can I resolve this freezing problem, or how can I execute the aforementioned method in a separate isolate?

Full code of my implementation:

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

  final picker = ImagePicker();

  Future<void> _pickImage() async {
    final settings = context.read<AppSettingsState>();

    try {
      XFile? pickedFile = await picker.pickImage(source: ImageSource.gallery);

      if (pickedFile != null) {
        settings.setImageLoading(true);
        await Future.delayed(const Duration(milliseconds: 500));

        File file =
            await FlutterExifRotation.rotateImage(path: pickedFile.path);

        if (Platform.isIOS) {
          final bytes = await File(file.path).readAsBytes();
          final img.Image? image = img.decodeImage(bytes);
          if (image != null) {
            final img.Image orientedImage = img.bakeOrientation(image);
            await File(file.path)
                .writeAsBytes(img.encodeJpg(orientedImage, quality: 90));
          }
        }

        if (mounted) {
          widget.selectImage(file);

          if (mounted) setState(() {});
        }
      }
    } catch (e) {
      log('Error picking image: $e');
      if (kDebugMode) showMessage('Error picking image: $e');
    } finally {
      await Future.delayed(const Duration(milliseconds: 500));
      settings.setImageLoading(false);
    }
  }
0

There are 0 best solutions below