react-native-compressor icon indicating copy to clipboard operation
react-native-compressor copied to clipboard

Unwanted image rotation on newer Androids after compression

Open MrTurtlev2 opened this issue 1 year ago • 15 comments

Android >= 12 ReactNative: 0.68.0 react-native-compressor: 1.8.24

After compressing the image manually, it rotates by 90 degrees. However, the automatic compression method works correctly. This issue was also present on iOS, but it was resolved with version 1.8.24.

MrTurtlev2 avatar Mar 27 '24 11:03 MrTurtlev2

👋 @MrTurtlev2 Thanks for opening your issue here! If you find this package useful hit the star🌟!

github-actions[bot] avatar Mar 27 '24 11:03 github-actions[bot]

I have discovered a temporary solution for this problem.

Navigate to the "ImageCompressor.ks" file located at: node-modules/react-native-compressor/android/scr/main/java/com/reactnativecompressor/Image

Then, replace the current implementation of the "manualCompressImage" function with the following code:

fun manualCompressImage(imagePath: String?, options: ImageCompressorOptions, reactContext: ReactApplicationContext?): String? {
    val image = if (options.input === ImageCompressorOptions.InputType.base64) decodeImage(imagePath) else loadImage(imagePath)
    val resizedImage = resize(image, options.maxWidth, options.maxHeight)
    val isBase64 = options.returnableOutputType === ImageCompressorOptions.ReturnableOutputType.base64
    val uri = Uri.parse(imagePath)
    val imagePathNew = uri.path
    var scaledBitmap: Bitmap? = correctImageOrientation(resizedImage, imagePathNew)
    val imageDataByteArrayOutputStream = compress(scaledBitmap, options.output, options.quality, options.disablePngTransparency)
    val compressedImagePath = encodeImage(imageDataByteArrayOutputStream, isBase64, options.output.toString(), imagePath, reactContext)
    if (isCompressedSizeLessThanActualFile(imagePath!!, compressedImagePath)) {
        return compressedImagePath
    } else {
        MediaCache.deleteFile(compressedImagePath!!)
        return slashifyFilePath(imagePath)
    }
} 

after updating the code just patch package with patch-package

yarn patch-package react-native-compressor

MrTurtlev2 avatar Mar 27 '24 11:03 MrTurtlev2

I still have the issue with image with "front" camera device. The patch seems to work only on "back" camera

MatteoGauthier avatar Nov 15 '24 14:11 MatteoGauthier

Have you managed to solve this issue? I'm facing the same problem.

MayThinnCho avatar Nov 22 '24 15:11 MayThinnCho

I still have the issue with image with "front" camera device. The patch seems to work only on "back" camera

I found this only happened on android 14

nalendro16 avatar Mar 24 '25 09:03 nalendro16

I had the same issue when taking a photo using front camera on Android 14 with both compressionMode: 'auto' and compressionMode: 'manual'. Fix from the comment above didn't help in my case. Found the solution - replace correctImageOrientation with this implementation (NOTE: fixes the behaviour of compressionMode: 'auto'):

fun correctImageOrientation(bitmap: Bitmap?, imagePath: String?): Bitmap? {
    if (bitmap == null || imagePath == null) return bitmap

    return try {
        val exif = ExifInterface(imagePath)
        val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
        val matrix = Matrix()

        when (orientation) {
            ExifInterface.ORIENTATION_NORMAL -> return bitmap
            ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> {
                matrix.setScale(-1f, 1f)
            }
            ExifInterface.ORIENTATION_ROTATE_180 -> {
                matrix.setRotate(180f)
            }
            ExifInterface.ORIENTATION_FLIP_VERTICAL -> {
                matrix.setScale(1f, -1f)
            }
            ExifInterface.ORIENTATION_TRANSPOSE -> {
                matrix.setRotate(90f)
                matrix.postScale(-1f, 1f)
            }
            ExifInterface.ORIENTATION_ROTATE_90 -> {
                matrix.setRotate(90f)
            }
            ExifInterface.ORIENTATION_TRANSVERSE -> {
                matrix.setRotate(-90f)
                matrix.postScale(-1f, 1f)
            }
            ExifInterface.ORIENTATION_ROTATE_270 -> {
                matrix.setRotate(-90f)
            }
            else -> return bitmap
        }

        Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
    } catch (e: IOException) {
        e.printStackTrace()
        bitmap
    }
}

And then run yarn patch-package react-native-compressor Double check that patch has been applied via yarn

Rebuild the app

Equilibriumty avatar Apr 28 '25 12:04 Equilibriumty

I had the same issue when taking a photo using front camera on Android 14 with both compressionMode: 'auto' and compressionMode: 'manual'. Fix from the comment above didn't help in my case. Found the solution - replace correctImageOrientation with this implementation:

fun correctImageOrientation(bitmap: Bitmap?, imagePath: String?): Bitmap? { if (bitmap == null || imagePath == null) return bitmap

return try {
    val exif = ExifInterface(imagePath)
    val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
    val matrix = Matrix()

    when (orientation) {
        ExifInterface.ORIENTATION_NORMAL -> return bitmap
        ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> {
            matrix.setScale(-1f, 1f)
        }
        ExifInterface.ORIENTATION_ROTATE_180 -> {
            matrix.setRotate(180f)
        }
        ExifInterface.ORIENTATION_FLIP_VERTICAL -> {
            matrix.setScale(1f, -1f)
        }
        ExifInterface.ORIENTATION_TRANSPOSE -> {
            matrix.setRotate(90f)
            matrix.postScale(-1f, 1f)
        }
        ExifInterface.ORIENTATION_ROTATE_90 -> {
            matrix.setRotate(90f)
        }
        ExifInterface.ORIENTATION_TRANSVERSE -> {
            matrix.setRotate(-90f)
            matrix.postScale(-1f, 1f)
        }
        ExifInterface.ORIENTATION_ROTATE_270 -> {
            matrix.setRotate(-90f)
        }
        else -> return bitmap
    }

    Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
} catch (e: IOException) {
    e.printStackTrace()
    bitmap
}

} And then run yarn patch-package react-native-compressor Double check that patch has been applied via yarn

Rebuild the app

This Function is only used in the autoCompression Mode and if you are using Manual @MrTurtlev2 Code needs to be Added in the Manual Function so it can Correct the Orientation.

hashhirr avatar Apr 30 '25 10:04 hashhirr

I had the same issue when taking a photo using front camera on Android 14 with both compressionMode: 'auto' and compressionMode: 'manual'. Fix from the comment above didn't help in my case. Found the solution - replace correctImageOrientation with this implementation: fun correctImageOrientation(bitmap: Bitmap?, imagePath: String?): Bitmap? { if (bitmap == null || imagePath == null) return bitmap

return try {
    val exif = ExifInterface(imagePath)
    val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
    val matrix = Matrix()

    when (orientation) {
        ExifInterface.ORIENTATION_NORMAL -> return bitmap
        ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> {
            matrix.setScale(-1f, 1f)
        }
        ExifInterface.ORIENTATION_ROTATE_180 -> {
            matrix.setRotate(180f)
        }
        ExifInterface.ORIENTATION_FLIP_VERTICAL -> {
            matrix.setScale(1f, -1f)
        }
        ExifInterface.ORIENTATION_TRANSPOSE -> {
            matrix.setRotate(90f)
            matrix.postScale(-1f, 1f)
        }
        ExifInterface.ORIENTATION_ROTATE_90 -> {
            matrix.setRotate(90f)
        }
        ExifInterface.ORIENTATION_TRANSVERSE -> {
            matrix.setRotate(-90f)
            matrix.postScale(-1f, 1f)
        }
        ExifInterface.ORIENTATION_ROTATE_270 -> {
            matrix.setRotate(-90f)
        }
        else -> return bitmap
    }

    Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
} catch (e: IOException) {
    e.printStackTrace()
    bitmap
}

} And then run yarn patch-package react-native-compressor Double check that patch has been applied via yarn Rebuild the app

This Function is only used in the autoCompression Mode and if you are using Manual @MrTurtlev2 Code needs to be Added in the Manual Function so it can Correct the Orientation.

Yes, thanks for correcting me. I've updated my comment accordingly

Equilibriumty avatar May 02 '25 08:05 Equilibriumty

hey @numandev1 the solution by @MrTurtlev2 works, should this fix be added into future releases?

wongchs avatar Aug 06 '25 08:08 wongchs

Does it fix the issue for the front camera as well? @wongchs

XChikuX avatar Aug 16 '25 18:08 XChikuX

I have same problem on on Android devices

Android >= 10 react-native: 0.80.2 react-native-compressor: 1.12.0

TiTnOuK avatar Sep 03 '25 07:09 TiTnOuK

@numandev1 Any reason we are not merging these changes?

The above solutions provided by the community work great..

XChikuX avatar Sep 09 '25 18:09 XChikuX

@numandev1 Why don't respond to the issue? I think that is correct solution.

Rengod95 avatar Sep 22 '25 11:09 Rengod95

Any update about this problem?

anderpaz avatar Oct 20 '25 18:10 anderpaz

Hi guys, probably creator is busy because he didn't respond yet. Let me know if you want help with creating patch or something, currently it's only solution for applying that fix.

MrTurtlev2 avatar Oct 20 '25 19:10 MrTurtlev2