react-native-rectangle-doc-scanner 3.108.0 → 3.109.0
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/dist/FullDocScanner.js +31 -16
- package/package.json +1 -1
- package/src/FullDocScanner.tsx +38 -20
package/dist/FullDocScanner.js
CHANGED
|
@@ -59,9 +59,10 @@ try {
|
|
|
59
59
|
catch (error) {
|
|
60
60
|
console.warn('[FullDocScanner] react-native-image-rotate module unavailable. Image rotation fallback disabled.', error);
|
|
61
61
|
}
|
|
62
|
-
|
|
62
|
+
let expoManipulatorUnavailable = false;
|
|
63
|
+
const isExpoImageManipulatorAvailable = () => !!ImageManipulator?.manipulateAsync && !expoManipulatorUnavailable;
|
|
63
64
|
const isImageRotateAvailable = !!ImageRotate?.rotateImage;
|
|
64
|
-
const isImageRotationSupported = isExpoImageManipulatorAvailable || isImageRotateAvailable;
|
|
65
|
+
const isImageRotationSupported = () => isExpoImageManipulatorAvailable() || isImageRotateAvailable;
|
|
65
66
|
const stripFileUri = (value) => value.replace(/^file:\/\//, '');
|
|
66
67
|
const ensureFileUri = (value) => (value.startsWith('file://') ? value : `file://${value}`);
|
|
67
68
|
const getBase64FromImageStore = async (uri) => {
|
|
@@ -398,7 +399,7 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
|
|
|
398
399
|
});
|
|
399
400
|
}, []);
|
|
400
401
|
const handleRotateImage = (0, react_1.useCallback)((degrees) => {
|
|
401
|
-
if (!isImageRotationSupported) {
|
|
402
|
+
if (!isImageRotationSupported()) {
|
|
402
403
|
console.warn('[FullDocScanner] Image rotation requested but no rotation module is available.');
|
|
403
404
|
return;
|
|
404
405
|
}
|
|
@@ -436,18 +437,32 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
|
|
|
436
437
|
});
|
|
437
438
|
return;
|
|
438
439
|
}
|
|
439
|
-
if (isExpoImageManipulatorAvailable && ImageManipulator?.manipulateAsync) {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
440
|
+
if (isExpoImageManipulatorAvailable() && ImageManipulator?.manipulateAsync) {
|
|
441
|
+
try {
|
|
442
|
+
// expo-image-manipulator로 이미지 회전
|
|
443
|
+
const result = await ImageManipulator.manipulateAsync(croppedImageData.path, [{ rotate: rotationNormalized }], {
|
|
444
|
+
compress: 0.9,
|
|
445
|
+
format: ImageManipulator.SaveFormat.JPEG,
|
|
446
|
+
base64: true,
|
|
447
|
+
});
|
|
448
|
+
onResult({
|
|
449
|
+
path: result.uri,
|
|
450
|
+
base64: result.base64,
|
|
451
|
+
});
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
catch (manipulatorError) {
|
|
455
|
+
const code = manipulatorError && typeof manipulatorError === 'object' && 'code' in manipulatorError
|
|
456
|
+
? String(manipulatorError.code)
|
|
457
|
+
: undefined;
|
|
458
|
+
if (code === 'ERR_UNAVAILABLE') {
|
|
459
|
+
expoManipulatorUnavailable = true;
|
|
460
|
+
console.warn('[FullDocScanner] expo-image-manipulator unavailable at runtime. Falling back to react-native-image-rotate if possible.');
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
throw manipulatorError;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
451
466
|
}
|
|
452
467
|
if (isImageRotateAvailable && ImageRotate?.rotateImage) {
|
|
453
468
|
const sourceUri = ensureFileUri(croppedImageData.path);
|
|
@@ -559,7 +574,7 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
|
|
|
559
574
|
croppedImageData ? (
|
|
560
575
|
// check_DP: Show confirmation screen
|
|
561
576
|
react_1.default.createElement(react_native_1.View, { style: styles.confirmationContainer },
|
|
562
|
-
isImageRotationSupported ? (react_1.default.createElement(react_native_1.View, { style: styles.rotateButtonsCenter },
|
|
577
|
+
isImageRotationSupported() ? (react_1.default.createElement(react_native_1.View, { style: styles.rotateButtonsCenter },
|
|
563
578
|
react_1.default.createElement(react_native_1.TouchableOpacity, { style: styles.rotateButtonTop, onPress: () => handleRotateImage(-90), accessibilityLabel: "\uC67C\uCABD\uC73C\uB85C 90\uB3C4 \uD68C\uC804", accessibilityRole: "button" },
|
|
564
579
|
react_1.default.createElement(react_native_1.Text, { style: styles.rotateIconText }, "\u21BA"),
|
|
565
580
|
react_1.default.createElement(react_native_1.Text, { style: styles.rotateButtonLabel }, "\uC88C\uB85C 90\u00B0")),
|
package/package.json
CHANGED
package/src/FullDocScanner.tsx
CHANGED
|
@@ -64,9 +64,11 @@ try {
|
|
|
64
64
|
);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
let expoManipulatorUnavailable = false;
|
|
68
|
+
const isExpoImageManipulatorAvailable = () =>
|
|
69
|
+
!!ImageManipulator?.manipulateAsync && !expoManipulatorUnavailable;
|
|
68
70
|
const isImageRotateAvailable = !!ImageRotate?.rotateImage;
|
|
69
|
-
const isImageRotationSupported = isExpoImageManipulatorAvailable || isImageRotateAvailable;
|
|
71
|
+
const isImageRotationSupported = () => isExpoImageManipulatorAvailable() || isImageRotateAvailable;
|
|
70
72
|
|
|
71
73
|
const stripFileUri = (value: string) => value.replace(/^file:\/\//, '');
|
|
72
74
|
const ensureFileUri = (value: string) => (value.startsWith('file://') ? value : `file://${value}`);
|
|
@@ -555,7 +557,7 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
|
|
|
555
557
|
|
|
556
558
|
const handleRotateImage = useCallback(
|
|
557
559
|
(degrees: -90 | 90) => {
|
|
558
|
-
if (!isImageRotationSupported) {
|
|
560
|
+
if (!isImageRotationSupported()) {
|
|
559
561
|
console.warn(
|
|
560
562
|
'[FullDocScanner] Image rotation requested but no rotation module is available.',
|
|
561
563
|
);
|
|
@@ -602,23 +604,39 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
|
|
|
602
604
|
return;
|
|
603
605
|
}
|
|
604
606
|
|
|
605
|
-
if (isExpoImageManipulatorAvailable && ImageManipulator?.manipulateAsync) {
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
607
|
+
if (isExpoImageManipulatorAvailable() && ImageManipulator?.manipulateAsync) {
|
|
608
|
+
try {
|
|
609
|
+
// expo-image-manipulator로 이미지 회전
|
|
610
|
+
const result = await ImageManipulator.manipulateAsync(
|
|
611
|
+
croppedImageData.path,
|
|
612
|
+
[{ rotate: rotationNormalized }],
|
|
613
|
+
{
|
|
614
|
+
compress: 0.9,
|
|
615
|
+
format: ImageManipulator.SaveFormat.JPEG,
|
|
616
|
+
base64: true,
|
|
617
|
+
},
|
|
618
|
+
);
|
|
616
619
|
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
620
|
+
onResult({
|
|
621
|
+
path: result.uri,
|
|
622
|
+
base64: result.base64,
|
|
623
|
+
});
|
|
624
|
+
return;
|
|
625
|
+
} catch (manipulatorError) {
|
|
626
|
+
const code =
|
|
627
|
+
manipulatorError && typeof manipulatorError === 'object' && 'code' in manipulatorError
|
|
628
|
+
? String((manipulatorError as any).code)
|
|
629
|
+
: undefined;
|
|
630
|
+
|
|
631
|
+
if (code === 'ERR_UNAVAILABLE') {
|
|
632
|
+
expoManipulatorUnavailable = true;
|
|
633
|
+
console.warn(
|
|
634
|
+
'[FullDocScanner] expo-image-manipulator unavailable at runtime. Falling back to react-native-image-rotate if possible.',
|
|
635
|
+
);
|
|
636
|
+
} else {
|
|
637
|
+
throw manipulatorError;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
622
640
|
}
|
|
623
641
|
|
|
624
642
|
if (isImageRotateAvailable && ImageRotate?.rotateImage) {
|
|
@@ -750,7 +768,7 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
|
|
|
750
768
|
// check_DP: Show confirmation screen
|
|
751
769
|
<View style={styles.confirmationContainer}>
|
|
752
770
|
{/* 회전 버튼들 - 가운데 정렬 */}
|
|
753
|
-
{isImageRotationSupported ? (
|
|
771
|
+
{isImageRotationSupported() ? (
|
|
754
772
|
<View style={styles.rotateButtonsCenter}>
|
|
755
773
|
<TouchableOpacity
|
|
756
774
|
style={styles.rotateButtonTop}
|