react-native-compressor 1.13.0 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -115,7 +115,7 @@ dependencies {
115
115
  implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4"
116
116
  implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
117
117
  implementation 'org.mp4parser:isoparser:1.9.56'
118
- implementation 'com.github.banketree:AndroidLame-kotlin:v0.0.1'
118
+ implementation 'com.github.kaushik-naik:TAndroidLame:277c2ab4b0'
119
119
  implementation 'javazoom:jlayer:1.0.1'
120
120
  }
121
121
 
@@ -133,11 +133,20 @@ object ImageCompressor {
133
133
  }
134
134
 
135
135
  fun manualCompressImage(imagePath: String?, options: ImageCompressorOptions, reactContext: ReactApplicationContext?): String? {
136
- val image = if (options.input === ImageCompressorOptions.InputType.base64) decodeImage(imagePath) else loadImage(imagePath)
137
- val resizedImage = resize(image, options.maxWidth, options.maxHeight)
138
- val imageDataByteArrayOutputStream = compress(resizedImage, options.output, options.quality,options.disablePngTransparency)
139
- val isBase64 = options.returnableOutputType === ImageCompressorOptions.ReturnableOutputType.base64
140
- return encodeImage(imageDataByteArrayOutputStream, isBase64, options.output.toString(),imagePath, reactContext)
136
+ val image = if (options.input === ImageCompressorOptions.InputType.base64) decodeImage(imagePath) else loadImage(imagePath)
137
+ val resizedImage = resize(image, options.maxWidth, options.maxHeight)
138
+ val isBase64 = options.returnableOutputType === ImageCompressorOptions.ReturnableOutputType.base64
139
+ val uri = Uri.parse(imagePath)
140
+ val imagePathNew = uri.path
141
+ var scaledBitmap: Bitmap? = correctImageOrientation(resizedImage, imagePathNew)
142
+ val imageDataByteArrayOutputStream = compress(scaledBitmap, options.output, options.quality, options.disablePngTransparency)
143
+ val compressedImagePath = encodeImage(imageDataByteArrayOutputStream, isBase64, options.output.toString(), imagePath, reactContext)
144
+ if (isCompressedSizeLessThanActualFile(imagePath!!, compressedImagePath)) {
145
+ return compressedImagePath
146
+ } else {
147
+ MediaCache.deleteFile(compressedImagePath!!)
148
+ return slashifyFilePath(imagePath)
149
+ }
141
150
  }
142
151
 
143
152
  fun isCompressedSizeLessThanActualFile(sourceFileUrl: String,compressedFileUrl: String?): Boolean {
@@ -249,20 +258,45 @@ object ImageCompressor {
249
258
  }
250
259
 
251
260
  fun correctImageOrientation(bitmap: Bitmap?, imagePath: String?): Bitmap? {
261
+ if (bitmap == null || imagePath == null) return bitmap
262
+
252
263
  return try {
253
- val exif = ExifInterface(imagePath!!)
264
+ val exif = ExifInterface(imagePath)
254
265
  val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
255
266
  val matrix = Matrix()
267
+
256
268
  when (orientation) {
257
- ExifInterface.ORIENTATION_ROTATE_90 -> matrix.postRotate(90f)
258
- ExifInterface.ORIENTATION_ROTATE_180 -> matrix.postRotate(180f)
259
- ExifInterface.ORIENTATION_ROTATE_270 -> matrix.postRotate(270f)
260
- else -> return bitmap // No rotation needed
269
+ ExifInterface.ORIENTATION_NORMAL -> return bitmap
270
+ ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> {
271
+ matrix.setScale(-1f, 1f)
272
+ }
273
+ ExifInterface.ORIENTATION_ROTATE_180 -> {
274
+ matrix.setRotate(180f)
275
+ }
276
+ ExifInterface.ORIENTATION_FLIP_VERTICAL -> {
277
+ matrix.setScale(1f, -1f)
278
+ }
279
+ ExifInterface.ORIENTATION_TRANSPOSE -> {
280
+ matrix.setRotate(90f)
281
+ matrix.postScale(-1f, 1f)
282
+ }
283
+ ExifInterface.ORIENTATION_ROTATE_90 -> {
284
+ matrix.setRotate(90f)
285
+ }
286
+ ExifInterface.ORIENTATION_TRANSVERSE -> {
287
+ matrix.setRotate(-90f)
288
+ matrix.postScale(-1f, 1f)
289
+ }
290
+ ExifInterface.ORIENTATION_ROTATE_270 -> {
291
+ matrix.setRotate(-90f)
292
+ }
293
+ else -> return bitmap
261
294
  }
262
- Bitmap.createBitmap(bitmap!!, 0, 0, bitmap.width, bitmap.height, matrix, true)
295
+
296
+ Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
263
297
  } catch (e: IOException) {
264
298
  e.printStackTrace()
265
- bitmap // Return original bitmap if an error occurs
299
+ bitmap
266
300
  }
267
301
  }
268
302
  }
@@ -28,23 +28,47 @@ class ImageMain {
28
28
  static func getImageMetaData(_ filePath: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
29
29
  let options = ImageCompressorOptions.fromDictionary([:])
30
30
  ImageCompressor.getAbsoluteImagePath(filePath, options: options) { ImagePath in
31
- if ImagePath.hasPrefix("file://") {
32
- let absoluteImagePath = URL(string: ImagePath)!.path
33
- Utils.getFileSize(absoluteImagePath) { fileSize in
34
- let _extension = (absoluteImagePath as NSString).pathExtension
35
- let imageData = NSData(contentsOfFile: absoluteImagePath)!
36
- let imageSource = CGImageSourceCreateWithData(imageData, nil)!
37
- let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil)!
38
- let exif=imageProperties as NSDictionary
39
- let mutableExif = exif.mutableCopy() as! NSMutableDictionary
40
- if let fileSizeInt = Int(fileSize as! String) {
41
- mutableExif.setValue(fileSizeInt, forKey: "size")
42
- }
43
- mutableExif.setValue(_extension, forKey: "extension")
44
- resolve(mutableExif)
45
- } reject: { code, message, error in
46
- reject(code, message, error)
31
+ guard ImagePath.hasPrefix("file://") else {
32
+ reject("INVALID_PATH", "Image path must start with file://", nil)
33
+ return
34
+ }
35
+
36
+ guard let url = URL(string: ImagePath) else {
37
+ reject("INVALID_URL", "Failed to create URL from image path", nil)
38
+ return
39
+ }
40
+
41
+ let absoluteImagePath = url.path
42
+ let fileURL = url as CFURL
43
+
44
+ Utils.getFileSize(absoluteImagePath) { fileSize in
45
+ let _extension = (absoluteImagePath as NSString).pathExtension
46
+
47
+ // Use CGImageSourceCreateWithURL to avoid loading entire file into memory (prevents OOM crashes for large images)
48
+ guard let imageSource = CGImageSourceCreateWithURL(fileURL, nil) else {
49
+ reject("INVALID_IMAGE", "Failed to create image source from URL", nil)
50
+ return
51
+ }
52
+
53
+ guard let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) else {
54
+ reject("NO_PROPERTIES", "Failed to get image properties", nil)
55
+ return
56
+ }
57
+
58
+ let exif = imageProperties as NSDictionary
59
+ guard let mutableExif = exif.mutableCopy() as? NSMutableDictionary else {
60
+ reject("COPY_ERROR", "Failed to create mutable copy of image properties", nil)
61
+ return
62
+ }
63
+
64
+ if let fileSizeString = fileSize as? String, let fileSizeInt = Int(fileSizeString) {
65
+ mutableExif.setValue(fileSizeInt, forKey: "size")
47
66
  }
67
+
68
+ mutableExif.setValue(_extension, forKey: "extension")
69
+ resolve(mutableExif)
70
+ } reject: { code, message, error in
71
+ reject(code, message, error)
48
72
  }
49
73
  }
50
74
  }
@@ -70,6 +70,8 @@ class Utils {
70
70
  let fileSize = attrs[.size] as? UInt64 {
71
71
  let fileSizeString = String(fileSize)
72
72
  resolve(fileSizeString)
73
+ } else {
74
+ reject("FILE_SIZE_ERROR", "Failed to get file size for path: \(filePath)", nil)
73
75
  }
74
76
  }
75
77
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-compressor",
3
- "version": "1.13.0",
3
+ "version": "1.15.0",
4
4
  "description": "Compress Image, Video, and Audio same like Whatsapp & Auto/Manual Compression | Background Upload | Download File | Create Video Thumbnail",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",