react-native-expo-cropper 1.0.29 → 1.0.30

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 ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "presets": [
3
+ "@babel/preset-env",
4
+ "@babel/preset-react"
5
+ ]
6
+ }
7
+
package/App.js ADDED
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import { SafeAreaView, StatusBar, StyleSheet } from 'react-native';
3
+ import ImageCropper from './src/ImageCropper';
4
+
5
+ const App = () => {
6
+ const handleCrop = (uri) => {
7
+ console.log('Cropped Image URI:', uri);
8
+ };
9
+
10
+ return (
11
+ <>
12
+ <StatusBar backgroundColor="black" barStyle="light-content" />
13
+ <SafeAreaView style={styles.container}>
14
+ <ImageCropper onCrop={handleCrop} />
15
+ </SafeAreaView>
16
+ </>
17
+ );
18
+ };
19
+
20
+ const styles = StyleSheet.create({
21
+ container: {
22
+ flex: 1,
23
+ backgroundColor: 'black',
24
+ },
25
+ });
26
+
27
+ export default App;
package/app.json ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "expo": {}
3
+ }
@@ -0,0 +1,276 @@
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["default"] = CustomCamera;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ var _reactNative = require("react-native");
10
+ var _reactNativeSafeAreaContext = require("react-native-safe-area-context");
11
+ var _expoCamera = require("expo-camera");
12
+ var ImageManipulator = _interopRequireWildcard(require("expo-image-manipulator"));
13
+ 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 _t3 in e) "default" !== _t3 && {}.hasOwnProperty.call(e, _t3) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t3)) && (i.get || i.set) ? o(f, _t3, i) : f[_t3] = e[_t3]); return f; })(e, t); }
14
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
15
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
16
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
17
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
18
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
19
+ 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 }; })(); }
20
+ 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); }
21
+ 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); }
22
+ 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); }); }; }
23
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
24
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
25
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
26
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
27
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
28
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
29
+ var _Dimensions$get = _reactNative.Dimensions.get('window'),
30
+ width = _Dimensions$get.width;
31
+ function CustomCamera(_ref) {
32
+ var onPhotoCaptured = _ref.onPhotoCaptured;
33
+ var _useState = (0, _react.useState)(false),
34
+ _useState2 = _slicedToArray(_useState, 2),
35
+ isReady = _useState2[0],
36
+ setIsReady = _useState2[1];
37
+ var _useState3 = (0, _react.useState)(false),
38
+ _useState4 = _slicedToArray(_useState3, 2),
39
+ loadingBeforeCapture = _useState4[0],
40
+ setLoadingBeforeCapture = _useState4[1];
41
+ var _useState5 = (0, _react.useState)(null),
42
+ _useState6 = _slicedToArray(_useState5, 1),
43
+ setHasPermission = _useState6[0];
44
+ var cameraRef = (0, _react.useRef)(null);
45
+ var insets = (0, _reactNativeSafeAreaContext.useSafeAreaInsets)();
46
+ (0, _react.useEffect)(function () {
47
+ _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
48
+ var _yield$Camera$request, status;
49
+ return _regenerator().w(function (_context) {
50
+ while (1) switch (_context.n) {
51
+ case 0:
52
+ _context.n = 1;
53
+ return _expoCamera.Camera.requestCameraPermissionsAsync();
54
+ case 1:
55
+ _yield$Camera$request = _context.v;
56
+ status = _yield$Camera$request.status;
57
+ setHasPermission(status === 'granted');
58
+ case 2:
59
+ return _context.a(2);
60
+ }
61
+ }, _callee);
62
+ }))();
63
+ }, []);
64
+
65
+ // Helper function to wait for multiple render cycles (works on iOS)
66
+ var waitForRender = function waitForRender() {
67
+ var cycles = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 5;
68
+ return new Promise(function (resolve) {
69
+ var count = 0;
70
+ var _tick = function tick() {
71
+ count++;
72
+ if (count >= cycles) {
73
+ resolve();
74
+ } else {
75
+ setImmediate(_tick);
76
+ }
77
+ };
78
+ setImmediate(_tick);
79
+ });
80
+ };
81
+
82
+ // Helper function to fix image orientation (removes EXIF orientation)
83
+ var fixImageOrientation = /*#__PURE__*/function () {
84
+ var _ref3 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(uri) {
85
+ var fixedImage, _t;
86
+ return _regenerator().w(function (_context2) {
87
+ while (1) switch (_context2.p = _context2.n) {
88
+ case 0:
89
+ _context2.p = 0;
90
+ _context2.n = 1;
91
+ return ImageManipulator.manipulateAsync(uri, [], {
92
+ compress: 1,
93
+ format: ImageManipulator.SaveFormat.PNG
94
+ });
95
+ case 1:
96
+ fixedImage = _context2.v;
97
+ return _context2.a(2, fixedImage.uri);
98
+ case 2:
99
+ _context2.p = 2;
100
+ _t = _context2.v;
101
+ console.error("Error fixing image orientation:", _t);
102
+ return _context2.a(2, uri);
103
+ }
104
+ }, _callee2, null, [[0, 2]]);
105
+ }));
106
+ return function fixImageOrientation(_x) {
107
+ return _ref3.apply(this, arguments);
108
+ };
109
+ }();
110
+ var takePicture = /*#__PURE__*/function () {
111
+ var _ref4 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
112
+ var photo, fixedUri, _t2;
113
+ return _regenerator().w(function (_context3) {
114
+ while (1) switch (_context3.p = _context3.n) {
115
+ case 0:
116
+ if (!cameraRef.current) {
117
+ _context3.n = 6;
118
+ break;
119
+ }
120
+ _context3.p = 1;
121
+ // Show loading after a delay (using setImmediate for iOS compatibility)
122
+ waitForRender(20).then(function () {
123
+ setLoadingBeforeCapture(true);
124
+ });
125
+
126
+ // Wait a bit before taking picture (works on iOS)
127
+ _context3.n = 2;
128
+ return waitForRender(3);
129
+ case 2:
130
+ _context3.n = 3;
131
+ return cameraRef.current.takePictureAsync({
132
+ quality: 1,
133
+ shutterSound: false
134
+ });
135
+ case 3:
136
+ photo = _context3.v;
137
+ _context3.n = 4;
138
+ return fixImageOrientation(photo.uri);
139
+ case 4:
140
+ fixedUri = _context3.v;
141
+ onPhotoCaptured(fixedUri);
142
+ setLoadingBeforeCapture(false);
143
+ _context3.n = 6;
144
+ break;
145
+ case 5:
146
+ _context3.p = 5;
147
+ _t2 = _context3.v;
148
+ setLoadingBeforeCapture(false);
149
+ _reactNative.Alert.alert("Erreur");
150
+ case 6:
151
+ return _context3.a(2);
152
+ }
153
+ }, _callee3, null, [[1, 5]]);
154
+ }));
155
+ return function takePicture() {
156
+ return _ref4.apply(this, arguments);
157
+ };
158
+ }();
159
+ return /*#__PURE__*/_react["default"].createElement(_reactNative.SafeAreaView, {
160
+ style: styles.outerContainer
161
+ }, /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
162
+ style: styles.cameraWrapper
163
+ }, /*#__PURE__*/_react["default"].createElement(_expoCamera.CameraView, {
164
+ style: styles.camera,
165
+ facing: "back",
166
+ ref: cameraRef,
167
+ onCameraReady: function onCameraReady() {
168
+ return setIsReady(true);
169
+ }
170
+ }), loadingBeforeCapture && /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
171
+ style: styles.loadingOverlay
172
+ }, /*#__PURE__*/_react["default"].createElement(_reactNative.Image, {
173
+ source: require('../src/assets/loadingCamera.gif'),
174
+ style: styles.loadingGif,
175
+ resizeMode: "contain"
176
+ })), /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
177
+ style: styles.touchBlocker,
178
+ pointerEvents: "auto"
179
+ })), /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
180
+ style: styles.scanFrame
181
+ })), /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
182
+ style: [styles.buttonContainer, {
183
+ bottom: ((insets === null || insets === void 0 ? void 0 : insets.bottom) || 0) + 16,
184
+ marginBottom: 0
185
+ }]
186
+ }, /*#__PURE__*/_react["default"].createElement(_reactNative.TouchableOpacity, {
187
+ style: styles.button,
188
+ onPress: takePicture,
189
+ disabled: !isReady || loadingBeforeCapture
190
+ })));
191
+ }
192
+ var PRIMARY_GREEN = '#198754';
193
+ var DEEP_BLACK = '#0B0B0B';
194
+ var GLOW_WHITE = 'rgba(255, 255, 255, 0.85)';
195
+ var styles = _reactNative.StyleSheet.create({
196
+ outerContainer: {
197
+ flex: 1,
198
+ backgroundColor: DEEP_BLACK,
199
+ justifyContent: 'center',
200
+ alignItems: 'center'
201
+ },
202
+ cameraWrapper: {
203
+ width: width,
204
+ aspectRatio: 9 / 16,
205
+ borderRadius: 30,
206
+ overflow: 'hidden',
207
+ alignItems: 'center',
208
+ justifyContent: 'center',
209
+ position: 'relative'
210
+ },
211
+ camera: _objectSpread({}, _reactNative.StyleSheet.absoluteFillObject),
212
+ scanFrame: {
213
+ position: 'absolute',
214
+ width: '95%',
215
+ height: '80%',
216
+ borderWidth: 4,
217
+ borderColor: PRIMARY_GREEN,
218
+ borderRadius: 5,
219
+ backgroundColor: 'rgba(0, 0, 0, 0.1)'
220
+ },
221
+ loadingOverlay: _objectSpread(_objectSpread({}, _reactNative.StyleSheet.absoluteFillObject), {}, {
222
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
223
+ zIndex: 20,
224
+ justifyContent: 'center',
225
+ alignItems: 'center'
226
+ }),
227
+ loadingGif: {
228
+ width: 100,
229
+ height: 100
230
+ },
231
+ touchBlocker: _objectSpread(_objectSpread({}, _reactNative.StyleSheet.absoluteFillObject), {}, {
232
+ zIndex: 21,
233
+ backgroundColor: 'transparent'
234
+ }),
235
+ cancelIcon: {
236
+ position: 'absolute',
237
+ top: 20,
238
+ left: 20,
239
+ backgroundColor: PRIMARY_GREEN,
240
+ borderRadius: 5,
241
+ padding: 8
242
+ },
243
+ buttonContainer: {
244
+ position: 'absolute',
245
+ bottom: 0,
246
+ marginBottom: 20,
247
+ flexDirection: 'row',
248
+ justifyContent: 'center'
249
+ },
250
+ button: {
251
+ width: 80,
252
+ height: 80,
253
+ borderRadius: 50,
254
+ backgroundColor: GLOW_WHITE,
255
+ borderWidth: 5,
256
+ borderColor: PRIMARY_GREEN,
257
+ alignItems: 'center',
258
+ justifyContent: 'center'
259
+ },
260
+ text: {
261
+ fontSize: 18,
262
+ color: GLOW_WHITE
263
+ },
264
+ container: {
265
+ flex: 1,
266
+ backgroundColor: DEEP_BLACK,
267
+ justifyContent: 'center',
268
+ alignItems: 'center',
269
+ padding: 20
270
+ },
271
+ iconText: {
272
+ fontSize: 18,
273
+ color: GLOW_WHITE,
274
+ fontWeight: '600'
275
+ }
276
+ });
@@ -0,0 +1,352 @@
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["default"] = void 0;
8
+ var _ImageCropperStyles = _interopRequireDefault(require("./ImageCropperStyles"));
9
+ var _react = _interopRequireWildcard(require("react"));
10
+ var _reactNative = require("react-native");
11
+ var _reactNativeSvg = _interopRequireWildcard(require("react-native-svg"));
12
+ var _reactNativeViewShot = require("react-native-view-shot");
13
+ var _CustomCamera = _interopRequireDefault(require("./CustomCamera"));
14
+ var _ImageProcessor = require("./ImageProcessor");
15
+ 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); }
16
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
17
+ 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 }; })(); }
18
+ 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); }
19
+ 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); }
20
+ 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); }); }; }
21
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
22
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
23
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
24
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
25
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
26
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
27
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
28
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
29
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
30
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
31
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
32
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
33
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
34
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
35
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
36
+ var ImageCropper = function ImageCropper(_ref) {
37
+ var onConfirm = _ref.onConfirm,
38
+ openCameraFirst = _ref.openCameraFirst,
39
+ initialImage = _ref.initialImage,
40
+ addheight = _ref.addheight;
41
+ var _useState = (0, _react.useState)(null),
42
+ _useState2 = _slicedToArray(_useState, 2),
43
+ image = _useState2[0],
44
+ setImage = _useState2[1];
45
+ var _useState3 = (0, _react.useState)([]),
46
+ _useState4 = _slicedToArray(_useState3, 2),
47
+ points = _useState4[0],
48
+ setPoints = _useState4[1];
49
+ var _useState5 = (0, _react.useState)(false),
50
+ _useState6 = _slicedToArray(_useState5, 2),
51
+ showResult = _useState6[0],
52
+ setShowResult = _useState6[1];
53
+ var _useState7 = (0, _react.useState)(false),
54
+ _useState8 = _slicedToArray(_useState7, 2),
55
+ showCustomCamera = _useState8[0],
56
+ setShowCustomCamera = _useState8[1];
57
+ var viewRef = (0, _react.useRef)(null);
58
+ var imageMeasure = (0, _react.useRef)({
59
+ x: 0,
60
+ y: 0,
61
+ width: 0,
62
+ height: 0
63
+ });
64
+ var selectedPointIndex = (0, _react.useRef)(null);
65
+ var lastTap = (0, _react.useRef)(null);
66
+ var _useState9 = (0, _react.useState)(false),
67
+ _useState0 = _slicedToArray(_useState9, 2),
68
+ isLoading = _useState0[0],
69
+ setIsLoading = _useState0[1];
70
+ var _useState1 = (0, _react.useState)(false),
71
+ _useState10 = _slicedToArray(_useState1, 2),
72
+ showFullScreenCapture = _useState10[0],
73
+ setShowFullScreenCapture = _useState10[1];
74
+ var lastValidPosition = (0, _react.useRef)(null);
75
+ (0, _react.useEffect)(function () {
76
+ if (openCameraFirst) {
77
+ setShowCustomCamera(true);
78
+ } else if (initialImage) {
79
+ setImage(initialImage);
80
+ }
81
+ }, [openCameraFirst, initialImage]);
82
+ (0, _react.useEffect)(function () {
83
+ if (!image) return;
84
+ _reactNative.Image.getSize(image, function (imgWidth, imgHeight) {
85
+ var screenRatio = SCREEN_WIDTH / SCREEN_HEIGHT;
86
+ var imageRatio = imgWidth / imgHeight;
87
+ if (imageRatio > screenRatio) {
88
+ imageMeasure.current = {
89
+ width: SCREEN_WIDTH,
90
+ height: SCREEN_WIDTH / imageRatio
91
+ };
92
+ } else {
93
+ imageMeasure.current = {
94
+ width: SCREEN_HEIGHT * imageRatio,
95
+ height: SCREEN_HEIGHT
96
+ };
97
+ }
98
+ });
99
+ }, [image]);
100
+ var initializeCropBox = function initializeCropBox() {
101
+ var _imageMeasure$current = imageMeasure.current,
102
+ width = _imageMeasure$current.width,
103
+ height = _imageMeasure$current.height;
104
+ // if (width === 0 || height === 0 || points.length > 0) return;
105
+ var boxWidth = width * 0.8;
106
+ var boxHeight = height * 0.8;
107
+ var centerX = width / 2;
108
+ var centerY = height / 2;
109
+ setPoints([{
110
+ x: centerX - boxWidth / 2,
111
+ y: centerY - boxHeight / 2
112
+ }, {
113
+ x: centerX + boxWidth / 2,
114
+ y: centerY - boxHeight / 2
115
+ }, {
116
+ x: centerX + boxWidth / 2,
117
+ y: centerY + boxHeight / 2
118
+ }, {
119
+ x: centerX - boxWidth / 2,
120
+ y: centerY + boxHeight / 2
121
+ }]);
122
+ };
123
+ var onImageLayout = function onImageLayout(e) {
124
+ var layout = e.nativeEvent.layout;
125
+ imageMeasure.current = {
126
+ x: layout.x,
127
+ y: layout.y,
128
+ width: layout.width,
129
+ height: layout.height
130
+ };
131
+ initializeCropBox();
132
+ };
133
+ var createPath = function createPath() {
134
+ if (points.length < 1) return '';
135
+ var path = "M ".concat(points[0].x, " ").concat(points[0].y, " ");
136
+ points.forEach(function (point) {
137
+ return path += "L ".concat(point.x, " ").concat(point.y, " ");
138
+ });
139
+ return path + 'Z';
140
+ };
141
+ var handleTap = function handleTap(e) {
142
+ if (!image || showResult) return;
143
+ var now = Date.now();
144
+ var _e$nativeEvent = e.nativeEvent,
145
+ tapX = _e$nativeEvent.locationX,
146
+ tapY = _e$nativeEvent.locationY;
147
+ if (lastTap.current && now - lastTap.current < 300) {
148
+ var exists = points.some(function (p) {
149
+ return Math.abs(p.x - tapX) < 15 && Math.abs(p.y - tapY) < 15;
150
+ });
151
+ if (!exists) setPoints([].concat(_toConsumableArray(points), [{
152
+ x: tapX,
153
+ y: tapY
154
+ }]));
155
+ lastTap.current = null;
156
+ } else {
157
+ var index = points.findIndex(function (p) {
158
+ return Math.abs(p.x - tapX) < 20 && Math.abs(p.y - tapY) < 20;
159
+ });
160
+ if (index !== -1) {
161
+ selectedPointIndex.current = index;
162
+ lastValidPosition.current = _objectSpread({}, points[index]); // store original position before move
163
+ }
164
+ lastTap.current = now;
165
+ }
166
+ };
167
+ var handleMove = function handleMove(e) {
168
+ if (showResult || selectedPointIndex.current === null) return;
169
+ var _e$nativeEvent2 = e.nativeEvent,
170
+ moveX = _e$nativeEvent2.locationX,
171
+ moveY = _e$nativeEvent2.locationY;
172
+ var width = imageMeasure.current.width;
173
+ var height = imageMeasure.current.height;
174
+ var boundedX = Math.max(0, Math.min(moveX, width));
175
+ var boundedY = Math.max(0, Math.min(moveY, height));
176
+ var edgeThreshold = 10;
177
+ var isNearTopOrBottomEdge = boundedY <= edgeThreshold || boundedY >= height - edgeThreshold;
178
+ var isNearLeftOrRightEdge = boundedX <= edgeThreshold || boundedX >= width - edgeThreshold;
179
+ if (isNearTopOrBottomEdge || isNearLeftOrRightEdge) {
180
+ // Reset point to last known position
181
+ if (lastValidPosition.current && selectedPointIndex.current !== null) {
182
+ setPoints(function (prev) {
183
+ return prev.map(function (p, i) {
184
+ return i === selectedPointIndex.current ? lastValidPosition.current : p;
185
+ });
186
+ });
187
+ }
188
+ selectedPointIndex.current = null;
189
+ return;
190
+ }
191
+
192
+ // Valid move — update point and store as new last valid position
193
+ var updatedPoint = {
194
+ x: boundedX,
195
+ y: boundedY
196
+ };
197
+ lastValidPosition.current = updatedPoint;
198
+ setPoints(function (prev) {
199
+ return prev.map(function (p, i) {
200
+ return i === selectedPointIndex.current ? updatedPoint : p;
201
+ });
202
+ });
203
+ };
204
+ var handleRelease = function handleRelease() {
205
+ selectedPointIndex.current = null;
206
+ };
207
+ var handleReset = function handleReset() {
208
+ // setPoints([]);
209
+ initializeCropBox();
210
+ };
211
+
212
+ // Helper function to wait for multiple render cycles (works on iOS)
213
+ var waitForRender = function waitForRender() {
214
+ var cycles = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 5;
215
+ return new Promise(function (resolve) {
216
+ var count = 0;
217
+ var _tick = function tick() {
218
+ count++;
219
+ if (count >= cycles) {
220
+ resolve();
221
+ } else {
222
+ setImmediate(_tick);
223
+ }
224
+ };
225
+ setImmediate(_tick);
226
+ });
227
+ };
228
+ return /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
229
+ style: _ImageCropperStyles["default"].container
230
+ }, showCustomCamera ? /*#__PURE__*/_react["default"].createElement(_CustomCamera["default"], {
231
+ onPhotoCaptured: function onPhotoCaptured(uri) {
232
+ setImage(uri);
233
+ setShowCustomCamera(false);
234
+ },
235
+ onCancel: function onCancel() {
236
+ return setShowCustomCamera(false);
237
+ }
238
+ }) : /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, !showResult && /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
239
+ style: image ? _ImageCropperStyles["default"].buttonContainer : _ImageCropperStyles["default"].centerButtonsContainer
240
+ }, image && /*#__PURE__*/_react["default"].createElement(_reactNative.TouchableOpacity, {
241
+ style: _ImageCropperStyles["default"].button,
242
+ onPress: handleReset
243
+ }, /*#__PURE__*/_react["default"].createElement(_reactNative.Text, {
244
+ style: _ImageCropperStyles["default"].buttonText
245
+ }, "Reset")), image && /*#__PURE__*/_react["default"].createElement(_reactNative.TouchableOpacity, {
246
+ style: _ImageCropperStyles["default"].button,
247
+ onPress: /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
248
+ var capturedUri, enhancedUri, name, _t;
249
+ return _regenerator().w(function (_context) {
250
+ while (1) switch (_context.p = _context.n) {
251
+ case 0:
252
+ // setShowFullScreenCapture(true);
253
+ setIsLoading(true);
254
+ setShowResult(true);
255
+ _context.p = 1;
256
+ _context.n = 2;
257
+ return waitForRender(8);
258
+ case 2:
259
+ console.log("Starting capture...");
260
+ _context.n = 3;
261
+ return (0, _reactNativeViewShot.captureRef)(viewRef, {
262
+ format: 'png',
263
+ quality: 1
264
+ });
265
+ case 3:
266
+ capturedUri = _context.v;
267
+ console.log("Capture successful:", capturedUri);
268
+ if (capturedUri) {
269
+ _context.n = 4;
270
+ break;
271
+ }
272
+ throw new Error("Capture returned empty URI");
273
+ case 4:
274
+ console.log("Enhancing image...");
275
+ _context.n = 5;
276
+ return (0, _ImageProcessor.enhanceImage)(capturedUri, addheight);
277
+ case 5:
278
+ enhancedUri = _context.v;
279
+ console.log("Image enhanced:", enhancedUri);
280
+ name = "IMAGE XTK".concat(Date.now(), ".png");
281
+ if (onConfirm) {
282
+ console.log("Calling onConfirm with:", enhancedUri, name);
283
+ onConfirm(enhancedUri, name);
284
+ }
285
+ _context.n = 7;
286
+ break;
287
+ case 6:
288
+ _context.p = 6;
289
+ _t = _context.v;
290
+ console.error("Erreur lors de la capture :", _t);
291
+ alert("Erreur lors de la capture ! " + _t.message);
292
+ case 7:
293
+ _context.p = 7;
294
+ setShowResult(false);
295
+ setIsLoading(false);
296
+ setShowFullScreenCapture(false);
297
+ return _context.f(7);
298
+ case 8:
299
+ return _context.a(2);
300
+ }
301
+ }, _callee, null, [[1, 6, 7, 8]]);
302
+ }))
303
+ }, /*#__PURE__*/_react["default"].createElement(_reactNative.Text, {
304
+ style: _ImageCropperStyles["default"].buttonText
305
+ }, "Confirm"))), image && /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
306
+ ref: viewRef,
307
+ collapsable: false,
308
+ style: showFullScreenCapture ? _ImageCropperStyles["default"].fullscreenImageContainer : _ImageCropperStyles["default"].imageContainer,
309
+ onStartShouldSetResponder: function onStartShouldSetResponder() {
310
+ return true;
311
+ },
312
+ onResponderStart: handleTap,
313
+ onResponderMove: handleMove,
314
+ onResponderRelease: handleRelease
315
+ }, /*#__PURE__*/_react["default"].createElement(_reactNative.Image, {
316
+ source: {
317
+ uri: image
318
+ },
319
+ style: _ImageCropperStyles["default"].image,
320
+ onLayout: onImageLayout
321
+ }), /*#__PURE__*/_react["default"].createElement(_reactNativeSvg["default"], {
322
+ style: _ImageCropperStyles["default"].overlay
323
+ }, /*#__PURE__*/_react["default"].createElement(_reactNativeSvg.Path, {
324
+ d: "M 0 0 H ".concat(imageMeasure.current.width, " V ").concat(imageMeasure.current.height, " H 0 Z ").concat(createPath()),
325
+ fill: showResult ? 'white' : 'rgba(0, 0, 0, 0.8)',
326
+ fillRule: "evenodd"
327
+ }), !showResult && points.length > 0 && /*#__PURE__*/_react["default"].createElement(_reactNativeSvg.Path, {
328
+ d: createPath(),
329
+ fill: "transparent",
330
+ stroke: "white",
331
+ strokeWidth: 2
332
+ }), !showResult && points.map(function (point, index) {
333
+ return /*#__PURE__*/_react["default"].createElement(_reactNativeSvg.Circle, {
334
+ key: index,
335
+ cx: point.x,
336
+ cy: point.y,
337
+ r: 10,
338
+ fill: "white"
339
+ });
340
+ })))), /*#__PURE__*/_react["default"].createElement(_reactNative.Modal, {
341
+ visible: isLoading,
342
+ transparent: true,
343
+ animationType: "fade"
344
+ }, /*#__PURE__*/_react["default"].createElement(_reactNative.View, {
345
+ style: _ImageCropperStyles["default"].loadingOverlay
346
+ }, /*#__PURE__*/_react["default"].createElement(_reactNative.Image, {
347
+ source: require('../src/assets/loadingCamera.gif'),
348
+ style: _ImageCropperStyles["default"].loadingGif,
349
+ resizeMode: "contain"
350
+ }))));
351
+ };
352
+ var _default = exports["default"] = ImageCropper;
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+ var _reactNative = require("react-native");
8
+ var _Dimensions$get = _reactNative.Dimensions.get('window'),
9
+ SCREEN_WIDTH = _Dimensions$get.width,
10
+ SCREEN_HEIGHT = _Dimensions$get.height;
11
+ var IMAGE_HEIGHT = SCREEN_HEIGHT;
12
+ var IMAGE_WIDTH = SCREEN_WIDTH;
13
+ var PRIMARY_GREEN = '#198754';
14
+ var DEEP_BLACK = '#0B0B0B';
15
+ var GLOW_WHITE = 'rgba(255, 255, 255, 0.85)';
16
+ var styles = _reactNative.StyleSheet.create({
17
+ container: {
18
+ flex: 1,
19
+ alignItems: 'center',
20
+ backgroundColor: DEEP_BLACK
21
+ },
22
+ buttonContainer: {
23
+ position: 'absolute',
24
+ bottom: 50,
25
+ left: 0,
26
+ right: 0,
27
+ flexDirection: 'row',
28
+ flexWrap: 'wrap',
29
+ justifyContent: 'center',
30
+ alignItems: 'center',
31
+ paddingHorizontal: 10,
32
+ zIndex: 10
33
+ },
34
+ button: {
35
+ flex: 1,
36
+ width: "100%",
37
+ padding: 10,
38
+ alignItems: "center",
39
+ justifyContent: "center",
40
+ backgroundColor: "#549433",
41
+ borderRadius: 5,
42
+ marginBottom: 20,
43
+ marginRight: 5
44
+ },
45
+ buttonText: {
46
+ color: 'white',
47
+ fontSize: 18,
48
+ fontWeight: '600',
49
+ textAlign: 'center'
50
+ },
51
+ iconText: {
52
+ color: PRIMARY_GREEN,
53
+ fontSize: 16,
54
+ fontWeight: '600',
55
+ textAlign: 'center'
56
+ },
57
+ imageContainer: {
58
+ width: IMAGE_WIDTH,
59
+ height: "80%",
60
+ justifyContent: 'center',
61
+ alignItems: 'center',
62
+ overflow: 'hidden',
63
+ backgroundColor: 'black'
64
+ },
65
+ image: {
66
+ width: '100%',
67
+ height: '100%',
68
+ resizeMode: 'contain'
69
+ },
70
+ overlay: {
71
+ position: 'absolute',
72
+ top: 0,
73
+ left: 0,
74
+ width: '100%',
75
+ height: '100%',
76
+ zIndex: 1
77
+ },
78
+ croppedImage: {
79
+ width: IMAGE_WIDTH,
80
+ height: IMAGE_HEIGHT,
81
+ resizeMode: 'cover',
82
+ marginTop: 10,
83
+ borderWidth: 2,
84
+ borderColor: 'white',
85
+ borderRadius: 10
86
+ },
87
+ fixedButtonContainer: {
88
+ position: 'absolute',
89
+ bottom: 100,
90
+ left: 0,
91
+ right: 0,
92
+ flexDirection: 'row',
93
+ justifyContent: 'center',
94
+ flexWrap: 'wrap',
95
+ gap: 10,
96
+ paddingHorizontal: 10
97
+ },
98
+ fixedButton: {
99
+ backgroundColor: PRIMARY_GREEN,
100
+ paddingVertical: 18,
101
+ paddingHorizontal: 30,
102
+ borderRadius: 12,
103
+ margin: 6,
104
+ alignItems: 'center',
105
+ justifyContent: 'center',
106
+ borderWidth: 0,
107
+ width: SCREEN_WIDTH * 0.4,
108
+ height: 60
109
+ },
110
+ centerButtonsContainer: {
111
+ position: 'absolute',
112
+ bottom: 20,
113
+ left: 0,
114
+ right: 0,
115
+ alignItems: 'center',
116
+ justifyContent: 'center',
117
+ zIndex: 10,
118
+ gap: 10
119
+ },
120
+ welcomeText: {
121
+ position: 'absolute',
122
+ top: '40%',
123
+ left: 20,
124
+ right: 20,
125
+ textAlign: 'center',
126
+ color: GLOW_WHITE,
127
+ fontSize: 40,
128
+ fontWeight: '800',
129
+ zIndex: 10
130
+ },
131
+ startButton: {
132
+ backgroundColor: PRIMARY_GREEN,
133
+ paddingVertical: 18,
134
+ paddingHorizontal: 30,
135
+ borderRadius: 12,
136
+ margin: 6,
137
+ alignItems: 'center',
138
+ justifyContent: 'center',
139
+ borderWidth: 0,
140
+ width: SCREEN_WIDTH * 0.9,
141
+ height: 70
142
+ },
143
+ startButtonText: {
144
+ color: 'white',
145
+ fontSize: 18,
146
+ fontWeight: '600',
147
+ textAlign: 'center'
148
+ },
149
+ loadingOverlay: {
150
+ flex: 1,
151
+ backgroundColor: 'rgba(0,0,0,0.5)',
152
+ justifyContent: 'center',
153
+ alignItems: 'center',
154
+ position: 'absolute',
155
+ top: 0,
156
+ bottom: 0,
157
+ left: 0,
158
+ right: 0,
159
+ zIndex: 9999
160
+ },
161
+ loadingGif: {
162
+ width: 120,
163
+ height: 120
164
+ },
165
+ fullscreenImageContainer: {
166
+ position: 'absolute',
167
+ top: 0,
168
+ left: 0,
169
+ width: SCREEN_WIDTH,
170
+ height: SCREEN_HEIGHT,
171
+ backgroundColor: 'black',
172
+ justifyContent: 'center',
173
+ alignItems: 'center',
174
+ zIndex: 9999
175
+ }
176
+ });
177
+ var _default = exports["default"] = styles;
@@ -0,0 +1,53 @@
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
+ };
53
+ }();
package/index.js ADDED
@@ -0,0 +1,6 @@
1
+ import { registerRootComponent } from 'expo';
2
+ import App from './App';
3
+
4
+ registerRootComponent(App);
5
+
6
+
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "react-native-expo-cropper",
3
- "version": "1.0.29",
3
+ "version": "1.0.30",
4
4
  "description": "Recadrage polygonal d'images.",
5
- "main": "src/index.js",
5
+ "main": "index.js",
6
6
  "author": "PCS AGRI",
7
7
  "license": "MIT",
8
8
  "keywords": [
@@ -50,12 +50,5 @@
50
50
  "@babel/core": "^7.28.5",
51
51
  "@babel/preset-env": "^7.28.5",
52
52
  "@babel/preset-react": "^7.28.5"
53
- },
54
- "files": [
55
- "src",
56
- "README.MD"
57
- ],
58
- "publishConfig": {
59
- "access": "public"
60
53
  }
61
54
  }
@@ -11,6 +11,7 @@ import {
11
11
  } from 'react-native';
12
12
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
13
13
  import { Camera, CameraView } from 'expo-camera';
14
+ import * as ImageManipulator from 'expo-image-manipulator';
14
15
  const { width } = Dimensions.get('window');
15
16
 
16
17
  export default function CustomCamera({ onPhotoCaptured}) {
@@ -31,23 +32,57 @@ useEffect(() => {
31
32
 
32
33
 
33
34
 
35
+ // Helper function to wait for multiple render cycles (works on iOS)
36
+ const waitForRender = (cycles = 5) => {
37
+ return new Promise((resolve) => {
38
+ let count = 0;
39
+ const tick = () => {
40
+ count++;
41
+ if (count >= cycles) {
42
+ resolve();
43
+ } else {
44
+ setImmediate(tick);
45
+ }
46
+ };
47
+ setImmediate(tick);
48
+ });
49
+ };
50
+
51
+ // Helper function to fix image orientation (removes EXIF orientation)
52
+ const fixImageOrientation = async (uri) => {
53
+ try {
54
+ // Use manipulateAsync with empty array to fix orientation based on EXIF data
55
+ const fixedImage = await ImageManipulator.manipulateAsync(uri, [], {
56
+ compress: 1,
57
+ format: ImageManipulator.SaveFormat.PNG
58
+ });
59
+ return fixedImage.uri;
60
+ } catch (error) {
61
+ console.error("Error fixing image orientation:", error);
62
+ return uri; // Return original if fixing fails
63
+ }
64
+ };
65
+
34
66
  const takePicture = async () => {
35
67
  if (cameraRef.current) {
36
68
  try {
37
-
38
- setTimeout(() => {
69
+ // Show loading after a delay (using setImmediate for iOS compatibility)
70
+ waitForRender(20).then(() => {
39
71
  setLoadingBeforeCapture(true);
40
- }, 1000);
72
+ });
41
73
 
42
- await new Promise(resolve => setTimeout(resolve, 100));
74
+ // Wait a bit before taking picture (works on iOS)
75
+ await waitForRender(3);
43
76
 
44
77
  const photo = await cameraRef.current.takePictureAsync({
45
78
  quality: 1,
46
79
  shutterSound: false,
47
80
  });
48
81
 
82
+ // Fix orientation to preserve vertical/horizontal position as taken
83
+ const fixedUri = await fixImageOrientation(photo.uri);
49
84
 
50
- onPhotoCaptured(photo.uri);
85
+ onPhotoCaptured(fixedUri);
51
86
 
52
87
  setLoadingBeforeCapture(false);
53
88
  } catch (error) {
@@ -127,7 +162,7 @@ const styles = StyleSheet.create({
127
162
  borderWidth: 4,
128
163
  borderColor: PRIMARY_GREEN,
129
164
  borderRadius: 5,
130
- backgroundColor: 'rgba(255,255,255,0.2)',
165
+ backgroundColor: 'rgba(0, 0, 0, 0.1)',
131
166
  },
132
167
  loadingOverlay: {
133
168
  ...StyleSheet.absoluteFillObject,
@@ -60,8 +60,8 @@ const ImageCropper = ({ onConfirm, openCameraFirst, initialImage ,addheight}) =>
60
60
  const initializeCropBox = () => {
61
61
  const { width, height } = imageMeasure.current;
62
62
  // if (width === 0 || height === 0 || points.length > 0) return;
63
- const boxWidth = width * 0.6;
64
- const boxHeight = height * 0.6;
63
+ const boxWidth = width * 0.8;
64
+ const boxHeight = height * 0.8;
65
65
  const centerX = width / 2;
66
66
  const centerY = height / 2;
67
67
  setPoints([
@@ -160,6 +160,22 @@ const ImageCropper = ({ onConfirm, openCameraFirst, initialImage ,addheight}) =>
160
160
  initializeCropBox();
161
161
  };
162
162
 
163
+ // Helper function to wait for multiple render cycles (works on iOS)
164
+ const waitForRender = (cycles = 5) => {
165
+ return new Promise((resolve) => {
166
+ let count = 0;
167
+ const tick = () => {
168
+ count++;
169
+ if (count >= cycles) {
170
+ resolve();
171
+ } else {
172
+ setImmediate(tick);
173
+ }
174
+ };
175
+ setImmediate(tick);
176
+ });
177
+ };
178
+
163
179
 
164
180
  return (
165
181
  <View style={styles.container}>
@@ -187,29 +203,39 @@ const ImageCropper = ({ onConfirm, openCameraFirst, initialImage ,addheight}) =>
187
203
  setIsLoading(true);
188
204
  setShowResult(true);
189
205
  try {
190
- await new Promise((resolve) => requestAnimationFrame(resolve));
206
+ // Wait for UI to render - give React time to update the SVG with white fill
207
+ await waitForRender(8);
208
+
209
+ console.log("Starting capture...");
191
210
  const capturedUri = await captureRef(viewRef, {
192
211
  format: 'png',
193
212
  quality: 1,
194
213
  });
214
+ console.log("Capture successful:", capturedUri);
195
215
 
216
+ if (!capturedUri) {
217
+ throw new Error("Capture returned empty URI");
218
+ }
196
219
 
197
- const enhancedUri = await enhanceImage(capturedUri ,addheight);
198
- const name = `IMAGE XTK${Date.now()}.png`;
199
-
200
-
201
- if (onConfirm) {
202
- onConfirm(enhancedUri, name);
203
- }
204
- } catch (error) {
205
- console.error("Erreur lors de la capture :", error);
206
- alert("Erreur lors de la capture !");
207
- } finally {
208
- setShowResult(false);
209
- setIsLoading(false);
210
- setShowFullScreenCapture(false);
211
- }
212
- }}
220
+ console.log("Enhancing image...");
221
+ const enhancedUri = await enhanceImage(capturedUri, addheight);
222
+ console.log("Image enhanced:", enhancedUri);
223
+
224
+ const name = `IMAGE XTK${Date.now()}.png`;
225
+
226
+ if (onConfirm) {
227
+ console.log("Calling onConfirm with:", enhancedUri, name);
228
+ onConfirm(enhancedUri, name);
229
+ }
230
+ } catch (error) {
231
+ console.error("Erreur lors de la capture :", error);
232
+ alert("Erreur lors de la capture ! " + error.message);
233
+ } finally {
234
+ setShowResult(false);
235
+ setIsLoading(false);
236
+ setShowFullScreenCapture(false);
237
+ }
238
+ }}
213
239
  >
214
240
  <Text style={styles.buttonText}>Confirm</Text>
215
241
  </TouchableOpacity>
@@ -233,7 +259,7 @@ const ImageCropper = ({ onConfirm, openCameraFirst, initialImage ,addheight}) =>
233
259
  <Svg style={styles.overlay}>
234
260
  <Path
235
261
  d={`M 0 0 H ${imageMeasure.current.width} V ${imageMeasure.current.height} H 0 Z ${createPath()}`}
236
- fill={showResult ? 'white' : 'rgba(255, 255, 255, 0.8)'}
262
+ fill={showResult ? 'white' : 'rgba(0, 0, 0, 0.8)'}
237
263
  fillRule="evenodd"
238
264
  />
239
265
  {!showResult && points.length > 0 && (