react-native-expo-cropper 1.0.21 → 1.0.23

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.
package/.babelrc CHANGED
@@ -1,4 +1,7 @@
1
1
  {
2
- "presets": ["@babel/preset-env"]
2
+ "presets": [
3
+ "@babel/preset-env",
4
+ "@babel/preset-react"
5
+ ]
3
6
  }
4
7
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-expo-cropper",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "description": "Recadrage polygonal d'images.",
5
5
  "main": "index.js",
6
6
  "author": "PCS AGRI",
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "@expo/vector-icons": "^15.0.2",
24
- "expo": "^54.0.0",
24
+ "expo": "54.0.0",
25
25
  "expo-camera": "~17.0.8",
26
26
  "expo-image-manipulator": "~14.0.7",
27
27
  "expo-image-picker": "~17.0.8",
@@ -43,6 +43,12 @@
43
43
  "homepage": "https://github.com/pcsagri/react-native-expo-cropper#readme",
44
44
  "scripts": {
45
45
  "test": "echo \"Error: no test specified\" && exit 1",
46
- "build": "babel src --out-dir dist"
46
+ "build": "babel src --out-dir dist",
47
+ "build:lib": "babel src --out-dir lib"
48
+ },
49
+ "devDependencies": {
50
+ "@babel/cli": "^7.28.3",
51
+ "@babel/core": "^7.28.5",
52
+ "@babel/preset-env": "^7.28.5"
47
53
  }
48
54
  }
@@ -1,8 +1,8 @@
1
1
  import styles from './ImageCropperStyles';
2
2
  import React, { useState, useRef, useEffect } from 'react';
3
- import { Modal,View, Image, Dimensions, TouchableOpacity, Animated, Text, InteractionManager } from 'react-native';
3
+ import { Modal,View, Image, Dimensions, TouchableOpacity, Animated, Text } from 'react-native';
4
4
  import Svg, { Path, Circle } from 'react-native-svg';
5
- import { captureRef } from 'react-native-view-shot';
5
+ import * as ViewShot from 'react-native-view-shot';
6
6
  import CustomCamera from './CustomCamera';
7
7
  import { enhanceImage } from './ImageProcessor';
8
8
 
@@ -183,62 +183,33 @@ const ImageCropper = ({ onConfirm, openCameraFirst, initialImage ,addheight}) =>
183
183
  <TouchableOpacity
184
184
  style={styles.button}
185
185
  onPress={async () => {
186
+ // setShowFullScreenCapture(true);
187
+ setIsLoading(true);
188
+ setShowResult(true);
186
189
  try {
187
- // Yield for UI to settle to avoid ref invalidation on iOS
188
- await new Promise(resolve => InteractionManager.runAfterInteractions(resolve));
189
-
190
- // Use JPG + tmpfile for faster iOS snapshots and real file URIs
191
- const captureOptions = { format: 'jpg', quality: 1, result: 'tmpfile' };
192
-
193
- // Timeout wrapper to avoid indefinite hangs
194
- const withTimeout = (promise, ms) =>
195
- new Promise((resolve, reject) => {
196
- const t = setTimeout(() => reject(new Error('captureRef timeout')), ms);
197
- promise.then(
198
- v => { clearTimeout(t); resolve(v); },
199
- e => { clearTimeout(t); reject(e); }
200
- );
201
- });
202
-
203
- // Pass ref object directly (SDK 54 compatibility)
204
- const capturedUri = await withTimeout(captureRef(viewRef, captureOptions), 6000);
205
-
206
- // Try enhancement with a timeout; fallback to captured if slow/fails
207
- const enhanceWithTimeout = (promise, ms) =>
208
- new Promise((resolve) => {
209
- const t = setTimeout(() => resolve(null), ms);
210
- promise.then(uri => { clearTimeout(t); resolve(uri); })
211
- .catch(() => { clearTimeout(t); resolve(null); });
212
- });
213
-
214
- const enhancedUri = await enhanceWithTimeout(enhanceImage(capturedUri, addheight), 4000);
215
-
216
- const resultUri = enhancedUri || capturedUri || image;
217
- const name = `IMAGE XTK${Date.now()}.jpg`;
218
-
219
- if (onConfirm && resultUri) {
220
- // Invoke callback first, then clean up UI to avoid re-render churn
221
- setTimeout(() => onConfirm(resultUri, name), 0);
222
- }
223
-
224
- // Reset UI states after callback
225
- setShowResult(false);
226
- setIsLoading(false);
227
- setShowFullScreenCapture(false);
228
- } catch (error) {
229
- console.error("Erreur lors de la capture :", error);
230
- alert("Erreur lors de la capture !");
231
-
232
- // Fallback to original image to keep UX moving
233
- if (onConfirm && image) {
234
- const name = `IMAGE_FALLBACK_${Date.now()}.jpg`;
235
- setTimeout(() => onConfirm(image, name), 0);
236
- }
237
-
238
- setShowResult(false);
239
- setIsLoading(false);
240
- setShowFullScreenCapture(false);
241
- }
190
+
191
+ const capturedUri = await ViewShot.captureRef(viewRef.current, {
192
+ format: 'png',
193
+ quality: 1,
194
+ result: "tmpfile",
195
+ });
196
+
197
+
198
+ const enhancedUri = await enhanceImage(capturedUri ,addheight);
199
+ const name = `IMAGE XTK${Date.now()}.png`;
200
+
201
+
202
+ if (onConfirm) {
203
+ onConfirm(enhancedUri, name);
204
+ }
205
+ } catch (error) {
206
+ console.error("Erreur lors de la capture :", error);
207
+ alert("Erreur lors de la capture !");
208
+ } finally {
209
+ setShowResult(false);
210
+ setIsLoading(false);
211
+ setShowFullScreenCapture(false);
212
+ }
242
213
  }}
243
214
  >
244
215
  <Text style={styles.buttonText}>Confirm</Text>
@@ -1,28 +1,40 @@
1
- import * as ImageManipulator from 'expo-image-manipulator';
1
+ import * as ImageManipulator from "expo-image-manipulator";
2
+ import * as FileSystem from "expo-file-system";
2
3
 
3
- export const enhanceImage = async (uri , addheight) => {
4
+ export const enhanceImage = async (uri, addheight) => {
4
5
  try {
5
- const imageInfo = await ImageManipulator.manipulateAsync(uri, []);
6
- const ratio = imageInfo.height / imageInfo.width;
6
+ let fileUri = uri;
7
7
 
8
- const maxHeight = addheight;
9
- const newWidth = Math.round(maxHeight / ratio);
8
+ // Convert Base64 → file on iOS SDK54 if needed
9
+ if (uri.startsWith("data:image")) {
10
+ const base64 = uri.split(",")[1];
11
+ const filePath = `${FileSystem.cacheDirectory}crop_${Date.now()}.png`;
12
+
13
+ await FileSystem.writeAsStringAsync(filePath, base64, {
14
+ encoding: FileSystem.EncodingType.Base64,
15
+ });
16
+
17
+ fileUri = filePath;
18
+ }
19
+
20
+ const info = await ImageManipulator.manipulateAsync(fileUri, []);
21
+ const ratio = info.height / info.width;
22
+
23
+ const newWidth = Math.round(addheight / ratio);
10
24
  const newHeight = Math.round(newWidth * ratio);
11
25
 
12
- const result = await ImageManipulator.manipulateAsync(
13
- uri,
14
- [
15
- { resize: { width: newWidth, height: newHeight } },
16
- ],
26
+ const resized = await ImageManipulator.manipulateAsync(
27
+ fileUri,
28
+ [{ resize: { width: newWidth, height: newHeight } }],
17
29
  {
18
30
  compress: 1,
19
- format: ImageManipulator.SaveFormat.PNG
31
+ format: ImageManipulator.SaveFormat.PNG,
20
32
  }
21
33
  );
22
34
 
23
- return result.uri;
35
+ return resized.uri;
24
36
  } catch (error) {
25
- console.error("Erreur T404K:", error);
37
+ console.log("iOS SDK54 enhanceImage error:", error);
26
38
  return uri;
27
39
  }
28
40
  };