diff --git a/README.md b/README.md
index 4a02c39..67a79fa 100755
--- a/README.md
+++ b/README.md
@@ -54,16 +54,16 @@ ImageEditor.cropImage(uri, cropData).then((url) => {
| `displaySize` | No | Size to which you want to scale the cropped image |
| `resizeMode` | No | Resizing mode to use when scaling the image (iOS only, Android resize mode is always 'cover', Web - no support) **Default value**: 'contain' |
| `quality` | No | The quality of the resulting image, expressed as a value from `0.0` to `1.0`.
The value `0.0` represents the maximum compression (or lowest quality) while the value `1.0` represents the least compression (or best quality).
iOS supports only `JPEG` format, while Android/Web supports both `JPEG`, `WEBP` and `PNG` formats.
**Default value**: (iOS: `1`), (Android: `0.9`) |
-| `format` | No | **(WEB ONLY)** The format of the resulting image, possible values are `jpeg`, `png`, `webp`, **Default value**: `jpeg` |
+| `format` | No | The format of the resulting image, possible values are `jpeg`, `png`, `webp`.
**Default value**: based on the provided image; if value determination is not possible, `jpeg` will be used as a fallback.
`webp` isn't supported by iOS. |
```ts
cropData: ImageCropData = {
- offset: {x: number, y: number},
- size: {width: number, height: number},
- displaySize: {width: number, height: number},
+ offset: { x: number, y: number },
+ size: { width: number, height: number },
+ displaySize: { width: number, height: number },
resizeMode: 'contain' | 'cover' | 'stretch',
quality: number, // 0...1
- format: 'jpeg' | 'png' | 'webp' // web only
+ format: 'jpeg' | 'png' | 'webp',
};
```
diff --git a/android/src/main/java/com/reactnativecommunity/imageeditor/ImageEditorModuleImpl.kt b/android/src/main/java/com/reactnativecommunity/imageeditor/ImageEditorModuleImpl.kt
index f8d9b92..453c2d9 100644
--- a/android/src/main/java/com/reactnativecommunity/imageeditor/ImageEditorModuleImpl.kt
+++ b/android/src/main/java/com/reactnativecommunity/imageeditor/ImageEditorModuleImpl.kt
@@ -42,6 +42,12 @@ import kotlinx.coroutines.cancel
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
+object MimeType {
+ const val JPEG = "image/jpeg"
+ const val PNG = "image/png"
+ const val WEBP = "image/webp"
+}
+
class ImageEditorModuleImpl(private val reactContext: ReactApplicationContext) {
private val moduleCoroutineScope = CoroutineScope(Dispatchers.Default)
@@ -91,6 +97,7 @@ class ImageEditorModuleImpl(private val reactContext: ReactApplicationContext) {
* is passed to this is the file:// URI of the new image
*/
fun cropImage(uri: String?, options: ReadableMap, promise: Promise) {
+ val format = if (options.hasKey("format")) options.getString("format") else null
val offset = if (options.hasKey("offset")) options.getMap("offset") else null
val size = if (options.hasKey("size")) options.getMap("size") else null
val quality =
@@ -149,14 +156,10 @@ class ImageEditorModuleImpl(private val reactContext: ReactApplicationContext) {
if (cropped == null) {
throw IOException("Cannot decode bitmap: $uri")
}
- val mimeType = outOptions.outMimeType
- if (mimeType.isNullOrEmpty()) {
- throw IOException("Could not determine MIME type")
- }
-
+ val mimeType = getMimeType(outOptions, format)
val tempFile = createTempFile(reactContext, mimeType)
writeCompressedBitmapToFile(cropped, mimeType, tempFile, quality)
- if (mimeType == "image/jpeg") {
+ if (mimeType == MimeType.JPEG) {
copyExif(reactContext, Uri.parse(uri), tempFile)
}
promise.resolve(Uri.fromFile(tempFile).toString())
@@ -434,6 +437,20 @@ class ImageEditorModuleImpl(private val reactContext: ReactApplicationContext) {
)
// Utils
+ private fun getMimeType(outOptions: BitmapFactory.Options, format: String?): String {
+ val mimeType =
+ when (format) {
+ "webp" -> MimeType.WEBP
+ "png" -> MimeType.PNG
+ "jpeg" -> MimeType.JPEG
+ else -> outOptions.outMimeType
+ }
+ if (mimeType.isNullOrEmpty()) {
+ return MimeType.JPEG
+ }
+ return mimeType
+ }
+
private fun getOrientation(context: Context, uri: Uri): Int {
val file = getFileFromUri(context, uri)
if (file == null) {
@@ -501,8 +518,8 @@ class ImageEditorModuleImpl(private val reactContext: ReactApplicationContext) {
private fun getFileExtensionForType(mimeType: String?): String {
return when (mimeType) {
- "image/png" -> ".png"
- "image/webp" -> ".webp"
+ MimeType.PNG -> ".png"
+ MimeType.WEBP -> ".webp"
else -> ".jpg"
}
}
@@ -515,8 +532,8 @@ class ImageEditorModuleImpl(private val reactContext: ReactApplicationContext) {
@Suppress("DEPRECATION") CompressFormat.WEBP
}
return when (mimeType) {
- "image/png" -> CompressFormat.PNG
- "image/webp" -> webpCompressFormat
+ MimeType.PNG -> CompressFormat.PNG
+ MimeType.WEBP -> webpCompressFormat
else -> CompressFormat.JPEG
}
}
diff --git a/ios/RNCImageEditor.mm b/ios/RNCImageEditor.mm
index bc66552..148c147 100644
--- a/ios/RNCImageEditor.mm
+++ b/ios/RNCImageEditor.mm
@@ -46,6 +46,7 @@ - (void) cropImage:(NSString *)uri
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject
{
+ NSString *format = data.format();
CGSize size = [RCTConvert CGSize:@{ @"width": @(data.size().width()), @"height": @(data.size().height()) }];
CGPoint offset = [RCTConvert CGPoint:@{ @"x": @(data.offset().x()), @"y": @(data.offset().y()) }];
CGSize targetSize = size;
@@ -66,6 +67,7 @@ - (void) cropImage:(NSString *)uri
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)
{
+ NSString *format = cropData[@"format"];
CGSize size = [RCTConvert CGSize:cropData[@"size"]];
CGPoint offset = [RCTConvert CGPoint:cropData[@"offset"]];
CGSize targetSize = size;
@@ -82,6 +84,9 @@ - (void) cropImage:(NSString *)uri
NSURL *url = [imageRequest URL];
NSString *urlPath = [url path];
NSString *extension = [urlPath pathExtension];
+ if([format isEqualToString:@"png"] || [format isEqualToString:@"jpeg"]){
+ extension = format;
+ }
[[_bridge moduleForName:@"ImageLoader" lazilyLoadIfNecessary:YES] loadImageWithURLRequest:imageRequest callback:^(NSError *error, UIImage *image) {
if (error) {
diff --git a/src/NativeRNCImageEditor.ts b/src/NativeRNCImageEditor.ts
index 96db64c..896063a 100644
--- a/src/NativeRNCImageEditor.ts
+++ b/src/NativeRNCImageEditor.ts
@@ -40,6 +40,11 @@ export interface Spec extends TurboModule {
* (Optional) Compression quality jpg images (number from 0 to 1).
*/
quality?: Float;
+
+ /**
+ * (Optional) The format of the resulting image. Default auto-detection based on given image
+ */
+ format?: string;
}
): Promise;
}
diff --git a/src/index.ts b/src/index.ts
index 0a6e807..88ba526 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -8,6 +8,7 @@
import { Platform } from 'react-native';
import NativeRNCImageEditor from './NativeRNCImageEditor';
import type { Spec } from './NativeRNCImageEditor';
+import type { ImageCropData } from './types.ts';
const LINKING_ERROR =
`The package '@react-native-community/image-editor' doesn't seem to be linked. Make sure: \n\n` +
@@ -23,16 +24,6 @@ const RNCImageEditor: Spec = NativeRNCImageEditor
},
});
-type ImageCropDataFromSpec = Parameters[1];
-
-export interface ImageCropData
- extends Omit {
- resizeMode?: 'contain' | 'cover' | 'stretch';
- // ^^^ codegen doesn't support union types yet
- // so to provide more type safety we override the type here
- format?: 'png' | 'jpeg' | 'webp'; // web only
-}
-
class ImageEditor {
/**
* Crop the image specified by the URI param. If URI points to a remote
diff --git a/src/index.web.ts b/src/index.web.ts
index 0aefae7..761a642 100644
--- a/src/index.web.ts
+++ b/src/index.web.ts
@@ -1,14 +1,4 @@
-import type { Spec } from './NativeRNCImageEditor';
-
-type ImageCropDataFromSpec = Parameters[1];
-
-export interface ImageCropData
- extends Omit {
- resizeMode?: 'contain' | 'cover' | 'stretch';
- // ^^^ codegen doesn't support union types yet
- // so to provide more type safety we override the type here
- format?: 'png' | 'jpeg' | 'webp'; // web only
-}
+import type { ImageCropData } from './types.ts';
function drawImage(
img: HTMLImageElement,
diff --git a/src/types.ts b/src/types.ts
new file mode 100644
index 0000000..8647b38
--- /dev/null
+++ b/src/types.ts
@@ -0,0 +1,11 @@
+import type { Spec } from './NativeRNCImageEditor.ts';
+
+type ImageCropDataFromSpec = Parameters[1];
+
+export interface ImageCropData
+ extends Omit {
+ format?: 'png' | 'jpeg' | 'webp';
+ resizeMode?: 'contain' | 'cover' | 'stretch';
+ // ^^^ codegen doesn't support union types yet
+ // so to provide more type safety we override the type here
+}