react-native-expo-cropper 1.2.36 → 1.2.37

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.
@@ -1,53 +1,41 @@
1
- "use strict";
2
-
3
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.enhanceImage = void 0;
8
- var ImageManipulator = _interopRequireWildcard(require("expo-image-manipulator"));
9
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t2 in e) "default" !== _t2 && {}.hasOwnProperty.call(e, _t2) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t2)) && (i.get || i.set) ? o(f, _t2, i) : f[_t2] = e[_t2]); return f; })(e, t); }
10
- function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
11
- function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
12
- function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
13
- function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
14
- var enhanceImage = exports.enhanceImage = /*#__PURE__*/function () {
15
- var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(uri, addheight) {
16
- var imageInfo, ratio, maxHeight, newWidth, newHeight, result, _t;
17
- return _regenerator().w(function (_context) {
18
- while (1) switch (_context.p = _context.n) {
19
- case 0:
20
- _context.p = 0;
21
- _context.n = 1;
22
- return ImageManipulator.manipulateAsync(uri, []);
23
- case 1:
24
- imageInfo = _context.v;
25
- ratio = imageInfo.height / imageInfo.width;
26
- maxHeight = addheight;
27
- newWidth = Math.round(maxHeight / ratio);
28
- newHeight = Math.round(newWidth * ratio);
29
- _context.n = 2;
30
- return ImageManipulator.manipulateAsync(uri, [{
31
- resize: {
32
- width: newWidth,
33
- height: newHeight
34
- }
35
- }], {
36
- compress: 1,
37
- format: ImageManipulator.SaveFormat.PNG
38
- });
39
- case 2:
40
- result = _context.v;
41
- return _context.a(2, result.uri);
42
- case 3:
43
- _context.p = 3;
44
- _t = _context.v;
45
- console.error("Erreur T404K:", _t);
46
- return _context.a(2, uri);
47
- }
48
- }, _callee, null, [[0, 3]]);
49
- }));
50
- return function enhanceImage(_x, _x2) {
51
- return _ref.apply(this, arguments);
52
- };
1
+ "use strict";
2
+
3
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.enhanceImage = void 0;
8
+ var ImageManipulator = _interopRequireWildcard(require("expo-image-manipulator"));
9
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t2 in e) "default" !== _t2 && {}.hasOwnProperty.call(e, _t2) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t2)) && (i.get || i.set) ? o(f, _t2, i) : f[_t2] = e[_t2]); return f; })(e, t); }
10
+ function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
11
+ function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
12
+ function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
13
+ function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
14
+ /**
15
+ * Retourne l'image originale sans redimensionnement pour préserver la qualité maximale.
16
+ * Le redimensionnement destructif a été supprimé pour éviter la perte de résolution.
17
+ *
18
+ * @param {string} uri - URI de l'image originale
19
+ * @param {number} addheight - Paramètre conservé pour compatibilité (non utilisé)
20
+ * @returns {Promise<string>} URI de l'image originale (sans modification)
21
+ */
22
+ var enhanceImage = exports.enhanceImage = /*#__PURE__*/function () {
23
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(uri, addheight) {
24
+ var _t;
25
+ return _regenerator().w(function (_context) {
26
+ while (1) switch (_context.p = _context.n) {
27
+ case 0:
28
+ _context.p = 0;
29
+ return _context.a(2, uri);
30
+ case 1:
31
+ _context.p = 1;
32
+ _t = _context.v;
33
+ console.error("Erreur enhanceImage:", _t);
34
+ return _context.a(2, uri);
35
+ }
36
+ }, _callee, null, [[0, 1]]);
37
+ }));
38
+ return function enhanceImage(_x, _x2) {
39
+ return _ref.apply(this, arguments);
40
+ };
53
41
  }();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-expo-cropper",
3
- "version": "1.2.36",
3
+ "version": "1.2.37",
4
4
  "description": "Recadrage polygonal d'images.",
5
5
  "main": "index.js",
6
6
  "author": "PCS AGRI",
@@ -45,10 +45,10 @@
45
45
  "url": "https://github.com/pcsagri/react-native-expo-cropper/issues"
46
46
  },
47
47
  "homepage": "https://github.com/pcsagri/react-native-expo-cropper#readme",
48
- "scripts": {
49
- "test": "echo \"Error: no test specified\" && exit 1",
50
- "build": "npx babel src --out-dir dist"
51
- },
48
+ "scripts": {
49
+ "test": "echo \"Error: no test specified\" && exit 1",
50
+ "build": "npx --package=@babel/cli babel src --out-dir dist"
51
+ },
52
52
  "devDependencies": {
53
53
  "@babel/cli": "^7.28.3",
54
54
  "@babel/core": "^7.28.5",
@@ -13,23 +13,22 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
13
13
  import { Camera, CameraView } from 'expo-camera';
14
14
  const { width } = Dimensions.get('window');
15
15
 
16
- export default function CustomCamera({ onPhotoCaptured}) {
16
+ export default function CustomCamera({ onPhotoCaptured, onFrameCalculated }) {
17
17
  const [isReady, setIsReady] = useState(false);
18
18
  const [loadingBeforeCapture, setLoadingBeforeCapture] = useState(false);
19
19
  const [hasPermission, setHasPermission] = useState(null);
20
20
  const cameraRef = useRef(null);
21
+ const cameraWrapperRef = useRef(null);
21
22
  const insets = useSafeAreaInsets();
23
+ const [cameraWrapperLayout, setCameraWrapperLayout] = useState({ width: 0, height: 0, x: 0, y: 0 });
24
+ const [greenFrame, setGreenFrame] = useState(null);
22
25
 
23
-
24
-
25
- useEffect(() => {
26
- (async () => {
27
- const { status } = await Camera.requestCameraPermissionsAsync();
28
- setHasPermission(status === 'granted');
29
- })();
30
- }, []);
31
-
32
-
26
+ useEffect(() => {
27
+ (async () => {
28
+ const { status } = await Camera.requestCameraPermissionsAsync();
29
+ setHasPermission(status === 'granted');
30
+ })();
31
+ }, []);
33
32
 
34
33
  // Helper function to wait for multiple render cycles (works on iOS)
35
34
  const waitForRender = (cycles = 5) => {
@@ -49,6 +48,52 @@ useEffect(() => {
49
48
 
50
49
 
51
50
 
51
+ // ✅ CRITICAL FIX: Calculate green frame coordinates relative to camera preview
52
+ // The green frame should be calculated on the wrapper (as it's visually drawn there)
53
+ // But we store it with wrapper dimensions so ImageCropper can map it correctly
54
+ const calculateGreenFrameCoordinates = () => {
55
+ const wrapperWidth = cameraWrapperLayout.width;
56
+ const wrapperHeight = cameraWrapperLayout.height;
57
+
58
+ if (wrapperWidth === 0 || wrapperHeight === 0) {
59
+ console.warn("Camera wrapper layout not ready, cannot calculate green frame");
60
+ return null;
61
+ }
62
+
63
+ // ✅ Green frame dimensions: 80% width, 80% height (centered)
64
+ // The green frame should cover 80% of the image area, centered
65
+ const frameWidth = wrapperWidth * 0.80; // 80% width
66
+ const frameHeight = wrapperHeight * 0.80; // 80% height
67
+ const frameX = (wrapperWidth - frameWidth) / 2; // Centered horizontally
68
+ const frameY = (wrapperHeight - frameHeight) / 2; // Centered vertically
69
+
70
+ const frameCoords = {
71
+ x: frameX,
72
+ y: frameY,
73
+ width: frameWidth,
74
+ height: frameHeight,
75
+ wrapperWidth,
76
+ wrapperHeight,
77
+ // ✅ Store percentages for easier mapping later
78
+ percentX: (frameX / wrapperWidth) * 100,
79
+ percentY: (frameY / wrapperHeight) * 100,
80
+ percentWidth: 80,
81
+ percentHeight: 80
82
+ };
83
+
84
+ console.log("✅ Green frame coordinates calculated:", frameCoords);
85
+ return frameCoords;
86
+ };
87
+
88
+ // 🔁 Keep green frame state in sync with wrapper layout so we can both render it
89
+ // and send the exact same coordinates along with the captured photo.
90
+ useEffect(() => {
91
+ const coords = calculateGreenFrameCoordinates();
92
+ if (coords) {
93
+ setGreenFrame(coords);
94
+ }
95
+ }, [cameraWrapperLayout]);
96
+
52
97
  const takePicture = async () => {
53
98
  if (cameraRef.current) {
54
99
  try {
@@ -79,14 +124,21 @@ useEffect(() => {
79
124
  exif: photo.exif ? "present" : "missing"
80
125
  });
81
126
 
127
+ // ✅ CRITICAL FIX: Use the same green frame coordinates that are used for rendering
128
+ // Fallback to recalculation if, for some reason, state is not yet set
129
+ const greenFrameCoords = greenFrame || calculateGreenFrameCoordinates();
130
+
82
131
  // ✅ REFACTORISATION : Utiliser directement l'URI de la photo
83
132
  // L'orientation sera gérée dans ImageCropper si l'utilisateur utilise la fonction de rotation
84
133
  // skipProcessing: true préserve la qualité mais peut laisser l'orientation EXIF non appliquée
85
134
  // C'est acceptable car l'utilisateur peut corriger via la rotation dans ImageCropper
86
135
  const fixedUri = photo.uri;
87
136
 
88
- // Envoyer directement à ImageCropper (la qualité est préservée)
89
- onPhotoCaptured(fixedUri);
137
+ // Envoyer l'URI et les coordonnées du green frame à ImageCropper
138
+ onPhotoCaptured(fixedUri, {
139
+ greenFrame: greenFrameCoords,
140
+ capturedImageSize: { width: photo.width, height: photo.height }
141
+ });
90
142
  setLoadingBeforeCapture(false);
91
143
  } catch (error) {
92
144
  console.error("Error capturing photo:", error);
@@ -99,7 +151,20 @@ useEffect(() => {
99
151
 
100
152
  return (
101
153
  <SafeAreaView style={styles.outerContainer}>
102
- <View style={styles.cameraWrapper}>
154
+ <View
155
+ style={styles.cameraWrapper}
156
+ ref={cameraWrapperRef}
157
+ onLayout={(e) => {
158
+ const layout = e.nativeEvent.layout;
159
+ setCameraWrapperLayout({
160
+ width: layout.width,
161
+ height: layout.height,
162
+ x: layout.x,
163
+ y: layout.y
164
+ });
165
+ console.log("Camera wrapper layout updated:", layout);
166
+ }}
167
+ >
103
168
  <CameraView
104
169
  style={styles.camera}
105
170
  facing="back"
@@ -121,8 +186,20 @@ useEffect(() => {
121
186
  </>
122
187
  )}
123
188
 
124
- {/* Cadre de scan */}
125
- <View style={styles.scanFrame} />
189
+ {/* Cadre de scan - rendered using calculated coordinates (x, y, width, height) */}
190
+ {greenFrame && (
191
+ <View
192
+ style={[
193
+ styles.scanFrame,
194
+ {
195
+ left: greenFrame.x,
196
+ top: greenFrame.y,
197
+ width: greenFrame.width,
198
+ height: greenFrame.height,
199
+ },
200
+ ]}
201
+ />
202
+ )}
126
203
  </View>
127
204
 
128
205
  <View style={[styles.buttonContainer, { bottom: (insets?.bottom || 0) + 16, marginBottom: 0 }]}>
@@ -161,8 +238,6 @@ const styles = StyleSheet.create({
161
238
  },
162
239
  scanFrame: {
163
240
  position: 'absolute',
164
- width: '95%',
165
- height: '80%',
166
241
  borderWidth: 4,
167
242
  borderColor: PRIMARY_GREEN,
168
243
  borderRadius: 5,