Skip to content

Commit 4716a2d

Browse files
committed
Start implementation
1 parent 6c531f3 commit 4716a2d

File tree

6 files changed

+109
-3
lines changed

6 files changed

+109
-3
lines changed

android/src/main/java/com/margelo/nitro/multipleimagepicker/MultipleImagePickerImp.kt

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@ package com.margelo.nitro.multipleimagepicker
33
import android.app.Activity
44
import android.content.Context
55
import android.content.Intent
6+
import android.graphics.Bitmap
7+
import android.graphics.BitmapFactory
68
import android.graphics.Color
9+
import android.graphics.Matrix
710
import android.net.Uri
11+
import android.util.Log
12+
import androidx.exifinterface.media.ExifInterface
13+
import java.io.IOException
814
import androidx.core.content.ContextCompat
915
import com.facebook.react.bridge.BaseActivityEventListener
1016
import com.facebook.react.bridge.ColorPropConverter
@@ -163,7 +169,13 @@ class MultipleImagePickerImp(reactContext: ReactApplicationContext?) :
163169
localMedia.forEach { item ->
164170
if (item != null) {
165171
val media = getResult(item)
166-
data += media // Add the media to the data array
172+
// Adjust orientation using ExifInterface for Android (only for images)
173+
val adjustedMedia = if (media.type == ResultType.IMAGE) {
174+
adjustOrientation(media, item.path)
175+
} else {
176+
media
177+
}
178+
data += adjustedMedia // Add the media to the data array
167179
}
168180
}
169181
resolved(data)
@@ -634,6 +646,7 @@ class MultipleImagePickerImp(reactContext: ReactApplicationContext?) :
634646
parentFolderName = item.parentFolderName,
635647
creationDate = item.dateAddedTime.toDouble(),
636648
crop = item.isCut,
649+
orientation = null, // Will be populated by adjustOrientation for images
637650
path,
638651
type,
639652
fileName = item.fileName,
@@ -644,6 +657,55 @@ class MultipleImagePickerImp(reactContext: ReactApplicationContext?) :
644657
return media
645658
}
646659

660+
private fun adjustOrientation(pickerResult: PickerResult, filePath: String): PickerResult {
661+
try {
662+
val ei = ExifInterface(filePath)
663+
val orientation = ei.getAttributeInt(
664+
ExifInterface.TAG_ORIENTATION,
665+
ExifInterface.ORIENTATION_UNDEFINED
666+
)
667+
668+
val rotatedBitmap: Bitmap? = when (orientation) {
669+
ExifInterface.ORIENTATION_ROTATE_90 -> rotateImage(filePath, 90f)
670+
ExifInterface.ORIENTATION_ROTATE_180 -> rotateImage(filePath, 180f)
671+
ExifInterface.ORIENTATION_ROTATE_270 -> rotateImage(filePath, 270f)
672+
else -> BitmapFactory.decodeFile(filePath)
673+
}
674+
675+
rotatedBitmap?.let { bitmap ->
676+
val width = bitmap.width.toDouble()
677+
val height = bitmap.height.toDouble()
678+
// Update width, height, and orientation in pickerResult
679+
return pickerResult.copy(
680+
width = width,
681+
height = height,
682+
orientation = orientation.toDouble()
683+
)
684+
}
685+
} catch (e: IOException) {
686+
Log.e(TAG, "Failed to adjust orientation", e)
687+
}
688+
// Return with orientation info even if bitmap processing fails
689+
return try {
690+
val ei = ExifInterface(filePath)
691+
val orientation = ei.getAttributeInt(
692+
ExifInterface.TAG_ORIENTATION,
693+
ExifInterface.ORIENTATION_UNDEFINED
694+
)
695+
pickerResult.copy(orientation = orientation.toDouble())
696+
} catch (e: IOException) {
697+
Log.e(TAG, "Failed to read orientation", e)
698+
pickerResult
699+
}
700+
}
701+
702+
private fun rotateImage(filePath: String, degree: Float): Bitmap? {
703+
val bitmap = BitmapFactory.decodeFile(filePath)
704+
val matrix = Matrix()
705+
matrix.postRotate(degree)
706+
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
707+
}
708+
647709
override fun getAppContext(): Context {
648710
return reactApplicationContext
649711
}

nitrogen/generated/android/c++/JPickerResult.hpp

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/PickerResult.kt

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nitrogen/generated/ios/swift/PickerResult.swift

Lines changed: 24 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nitrogen/generated/shared/c++/PickerResult.hpp

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/types/result.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,16 @@ export interface PickerResult extends BaseResult {
150150
* Used to track image modifications
151151
*/
152152
crop?: boolean
153+
154+
/**
155+
* EXIF orientation value from the original image
156+
* Only applicable for image content, null for videos
157+
* Values correspond to EXIF orientation:
158+
* 1 = Normal (0°)
159+
* 3 = Upside down (180°)
160+
* 6 = Rotated 90° CW
161+
* 8 = Rotated 90° CCW
162+
* @example 6 // Image was rotated 90° clockwise
163+
*/
164+
orientation?: number
153165
}

0 commit comments

Comments
 (0)