Skip to content

Commit 4b612ce

Browse files
committed
feature: Add compression quality prop
1 parent ef8db2c commit 4b612ce

File tree

4 files changed

+27
-8
lines changed

4 files changed

+27
-8
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,15 @@ ImageEditor.cropImage(uri, cropData).then(url => {
4949
| `size` | Yes | Size (dimensions) of the cropped image |
5050
| `displaySize` | No | Size to which you want to scale the cropped image |
5151
| `resizeMode` | No | Resizing mode to use when scaling the image (iOS only, android resize mode is always 'cover') **Default value**: 'contain' |
52+
| `quality` | No | The quality of the resulting image, expressed as a value from `0.0` to `1.0`. <br/>The value `0.0` represents the maximum compression (or lowest quality) while the value `1.0` represents the least compression (or best quality).<br/>iOS supports only `JPEG` format, while Android supports both `JPEG`, `WEBP` and `PNG` formats.<br/>**Default value**: (iOS: `1`), (Android: `0.9`) |
5253

5354
```ts
5455
cropData: ImageCropData = {
5556
offset: {x: number, y: number},
5657
size: {width: number, height: number},
5758
displaySize: {width: number, height: number},
5859
resizeMode: 'contain' | 'cover' | 'stretch',
60+
quality: number // 0...1
5961
};
6062
```
6163

android/src/main/java/com/reactnativecommunity/imageeditor/ImageEditorModuleImpl.kt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ class ImageEditorModuleImpl(private val reactContext: ReactApplicationContext) {
9090
fun cropImage(uri: String?, options: ReadableMap, promise: Promise) {
9191
val offset = if (options.hasKey("offset")) options.getMap("offset") else null
9292
val size = if (options.hasKey("size")) options.getMap("size") else null
93+
val quality =
94+
if (options.hasKey("quality")) (options.getDouble("quality") * 100).toInt() else 90
9395
if (
9496
offset == null ||
9597
size == null ||
@@ -144,7 +146,7 @@ class ImageEditorModuleImpl(private val reactContext: ReactApplicationContext) {
144146
}
145147

146148
val tempFile = createTempFile(reactContext, mimeType)
147-
writeCompressedBitmapToFile(cropped, mimeType, tempFile)
149+
writeCompressedBitmapToFile(cropped, mimeType, tempFile, quality)
148150
if (mimeType == "image/jpeg") {
149151
copyExif(reactContext, Uri.parse(uri), tempFile)
150152
}
@@ -275,9 +277,6 @@ class ImageEditorModuleImpl(private val reactContext: ReactApplicationContext) {
275277
)
276278
private const val TEMP_FILE_PREFIX = "ReactNative_cropped_image_"
277279

278-
/** Compress quality of the output file. */
279-
private const val COMPRESS_QUALITY = 90
280-
281280
@SuppressLint("InlinedApi")
282281
private val EXIF_ATTRIBUTES =
283282
arrayOf(
@@ -374,9 +373,14 @@ class ImageEditorModuleImpl(private val reactContext: ReactApplicationContext) {
374373
}
375374

376375
@Throws(IOException::class)
377-
private fun writeCompressedBitmapToFile(cropped: Bitmap, mimeType: String, tempFile: File) {
376+
private fun writeCompressedBitmapToFile(
377+
cropped: Bitmap,
378+
mimeType: String,
379+
tempFile: File,
380+
compressQuality: Int
381+
) {
378382
FileOutputStream(tempFile).use {
379-
cropped.compress(getCompressFormatForType(mimeType), COMPRESS_QUALITY, it)
383+
cropped.compress(getCompressFormatForType(mimeType), compressQuality, it)
380384
}
381385
}
382386

ios/RNCImageEditor.mm

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ - (void) cropImage:(NSString *)uri
5656
}
5757
NSString *displaySize = data.resizeMode();
5858
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString: uri]];
59+
CGFloat compressionQuality = 1;
60+
if (data.quality().has_value()) {
61+
compressionQuality = *data.quality();
62+
}
5963
#else
6064
RCT_EXPORT_METHOD(cropImage:(NSURLRequest *)imageRequest
6165
cropData:(NSDictionary *)cropData
@@ -69,6 +73,10 @@ - (void) cropImage:(NSString *)uri
6973
if(displaySize){
7074
targetSize = [RCTConvert CGSize:cropData[@"displaySize"]];
7175
}
76+
CGFloat compressionQuality = 1;
77+
if(cropData[@"quality"]){
78+
compressionQuality = [RCTConvert CGFloat:cropData[@"quality"]];
79+
}
7280
#endif
7381
CGRect rect = {offset,size};
7482
NSURL *url = [imageRequest URL];
@@ -104,7 +112,7 @@ - (void) cropImage:(NSString *)uri
104112
}
105113
else{
106114

107-
imageData = UIImageJPEGRepresentation(croppedImage, 1);
115+
imageData = UIImageJPEGRepresentation(croppedImage, compressionQuality);
108116
path = [RNCFileSystem generatePathInDirectory:[[RNCFileSystem cacheDirectoryPath] stringByAppendingPathComponent:@"ReactNative_cropped_image_"] withExtension:@".jpg"];
109117
}
110118

src/NativeRNCImageEditor.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { TurboModule } from 'react-native';
2-
import type { Double } from 'react-native/Libraries/Types/CodegenTypes';
2+
import type { Double, Float } from 'react-native/Libraries/Types/CodegenTypes';
33
import { TurboModuleRegistry } from 'react-native';
44

55
export interface Spec extends TurboModule {
@@ -35,6 +35,11 @@ export interface Spec extends TurboModule {
3535
* `displaySize` param is not specified, this has no effect.
3636
*/
3737
resizeMode?: string;
38+
39+
/**
40+
* (Optional) Compression quality jpg images (number from 0 to 1).
41+
*/
42+
quality?: Float;
3843
}
3944
): Promise<string>;
4045
}

0 commit comments

Comments
 (0)