Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RangeError (index): Index out of range: index should be less than x: x #655

Open
wim-veninga opened this issue Jun 15, 2024 · 1 comment

Comments

@wim-veninga
Copy link

I'm selecting mutliple images via ImagePicker and passing them to a view model where I try to resize them. This is the code that does the resizing:

Future<File> resizeImageBasedOnFileSize(XFile file,
      {double targetSizeInBytes = 2 * 1024 * 1024}) async {
    File imageFile = File(file.path);
    int fileSize = await imageFile.length();
    //if (fileSize > targetSizeInBytes) {
    return await _createResizedImageFile(file, fileSize, targetSizeInBytes);
    //}
    //return imageFile;
  }

  Future<File> _createResizedImageFile(
      XFile file, int fileSize, double targetSizeInBytes) async {
    try {
      // Read the image bytes
      var bytes = await File(file.path).readAsBytes();

      Directory tempDir = await getTemporaryDirectory();
      String tempPath = '${tempDir.path}/raw_${file.name}.bin';
      File rawFile = File(tempPath);
      await rawFile.writeAsBytes(bytes);
      safePrint('Raw bytes data saved to: $tempPath');

      // Ensure the bytes are not empty
      if (bytes.isEmpty) {
        throw Exception("Image file is empty.");
      }

      // Find the appropriate decoder for the image data
      var decoder = img.findDecoderForData(bytes);
      if (decoder == null) {
        throw Exception("No suitable decoder found for the image data.");
      }

      // Decode the image
      var originalImage = decoder.decode(bytes);
      if (originalImage == null) {
        throw Exception("Failed to decode image.");
      }

      // Log the original image dimensions
      safePrint(
          "originalImage: ${originalImage.width}, ${originalImage.height}");

      // Calculate the scale factor and resize the image
      double scaleFactor = 1 / sqrt(fileSize / targetSizeInBytes);
      int newWidth = (originalImage.width * scaleFactor).round();
      img.Image resizedImage = img.copyResize(originalImage, width: newWidth);

      // Save the resized image to a file
      return await _saveResizedImageToFile(file, resizedImage);
    } catch (e) {
      safePrint("Error resizing image: $e");
      rethrow;
    }
  }

  Future<File> _saveResizedImageToFile(
      XFile file, img.Image resizedImage) async {
    Directory tempDir = await getTemporaryDirectory();
    String tempPath = '${tempDir.path}/resized_${file.name}.jpg';
    File resizedFile = File(tempPath);
    resizedFile.writeAsBytesSync(img.encodeJpg(resizedImage, quality: 100));
    return resizedFile;
  }

For certain images, the ones loaded on an andriod device via google photo's. The original photo's come from an ios device running ios 16. They are transfered to the andriod device via google photo's.
The call to decoder.decode(bytes) fails for the image file attached (in binary format, I took the Raw bytes data saved to: $tempPath' of the failing image). The error is RangeError (index): Index out of range: index should be less than 1608715: 1608715
raw_eedac95e-2e30-4201-bebe-58b29d31bb88-1_all_255.jpg.bin.txt

@koraxis
Copy link

koraxis commented Jul 16, 2024

I have the same problem with this scenario. Is there any update on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants