react-native-rectangle-doc-scanner 3.93.0 → 3.95.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
CHANGED
|
@@ -41,6 +41,7 @@ const react_1 = __importStar(require("react"));
|
|
|
41
41
|
const react_native_1 = require("react-native");
|
|
42
42
|
const react_native_image_picker_1 = require("react-native-image-picker");
|
|
43
43
|
const react_native_image_crop_picker_1 = __importDefault(require("react-native-image-crop-picker"));
|
|
44
|
+
const react_native_image_rotate_1 = __importDefault(require("react-native-image-rotate"));
|
|
44
45
|
const DocScanner_1 = require("./DocScanner");
|
|
45
46
|
const stripFileUri = (value) => value.replace(/^file:\/\//, '');
|
|
46
47
|
const CROPPER_TIMEOUT_MS = 8000;
|
|
@@ -329,53 +330,44 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
|
|
|
329
330
|
const handleFlashToggle = (0, react_1.useCallback)(() => {
|
|
330
331
|
setFlashEnabled(prev => !prev);
|
|
331
332
|
}, []);
|
|
332
|
-
const handleRotateImage = (0, react_1.useCallback)((degrees) => {
|
|
333
|
+
const handleRotateImage = (0, react_1.useCallback)(async (degrees) => {
|
|
333
334
|
if (!croppedImageData)
|
|
334
335
|
return;
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
compressImageQuality: 0.9,
|
|
353
|
-
cropperToolbarTitle: ' ',
|
|
354
|
-
cropperChooseText: '완료',
|
|
355
|
-
cropperCancelText: '취소',
|
|
356
|
-
cropperRotateButtonsHidden: false,
|
|
357
|
-
});
|
|
358
|
-
onResult({
|
|
359
|
-
path: rotatedImage.path,
|
|
360
|
-
base64: rotatedImage.data ?? undefined,
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
catch (error) {
|
|
364
|
-
console.error('[FullDocScanner] Image rotation error:', error);
|
|
365
|
-
// 에러 발생 시 원본 이미지 전송
|
|
366
|
-
onResult({
|
|
367
|
-
path: croppedImageData.path,
|
|
368
|
-
base64: croppedImageData.base64,
|
|
369
|
-
});
|
|
370
|
-
}
|
|
336
|
+
try {
|
|
337
|
+
// UI 회전 상태 먼저 업데이트 (즉각 반응)
|
|
338
|
+
setRotationDegrees(prev => {
|
|
339
|
+
const newRotation = (prev + degrees + 360) % 360;
|
|
340
|
+
return newRotation;
|
|
341
|
+
});
|
|
342
|
+
console.log('[FullDocScanner] Starting image rotation...');
|
|
343
|
+
// ImageRotate를 사용해서 실제로 이미지 회전 (UI 없이)
|
|
344
|
+
const rotatedImagePath = await react_native_image_rotate_1.default.rotateImage(croppedImageData.path, degrees);
|
|
345
|
+
console.log('[FullDocScanner] Image rotated successfully:', rotatedImagePath);
|
|
346
|
+
// 회전된 이미지로 교체
|
|
347
|
+
setCroppedImageData({
|
|
348
|
+
path: rotatedImagePath,
|
|
349
|
+
base64: undefined, // base64는 다시 읽어야 함
|
|
350
|
+
});
|
|
351
|
+
// rotation degrees는 0으로 리셋 (이미 실제 파일에 적용되었으므로)
|
|
352
|
+
setRotationDegrees(0);
|
|
371
353
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
354
|
+
catch (error) {
|
|
355
|
+
console.error('[FullDocScanner] Image rotation error:', error);
|
|
356
|
+
// 에러 발생 시 UI rotation 원복
|
|
357
|
+
setRotationDegrees(prev => {
|
|
358
|
+
const revertRotation = (prev - degrees + 360) % 360;
|
|
359
|
+
return revertRotation;
|
|
376
360
|
});
|
|
377
361
|
}
|
|
378
|
-
}, [croppedImageData
|
|
362
|
+
}, [croppedImageData]);
|
|
363
|
+
const handleConfirm = (0, react_1.useCallback)(() => {
|
|
364
|
+
if (!croppedImageData)
|
|
365
|
+
return;
|
|
366
|
+
onResult({
|
|
367
|
+
path: croppedImageData.path,
|
|
368
|
+
base64: croppedImageData.base64,
|
|
369
|
+
});
|
|
370
|
+
}, [croppedImageData, onResult]);
|
|
379
371
|
const handleRetake = (0, react_1.useCallback)(() => {
|
|
380
372
|
console.log('[FullDocScanner] Retake - clearing cropped image and resetting scanner');
|
|
381
373
|
setCroppedImageData(null);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-rectangle-doc-scanner",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.95.0",
|
|
4
4
|
"description": "Native-backed document scanner for React Native with customizable overlays.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -33,15 +33,19 @@
|
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"react": "*",
|
|
35
35
|
"react-native": "*",
|
|
36
|
-
"react-native-image-picker": "*",
|
|
37
36
|
"react-native-image-crop-picker": "*",
|
|
37
|
+
"react-native-image-picker": "*",
|
|
38
|
+
"react-native-image-rotate": "*",
|
|
38
39
|
"react-native-svg": "*"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
42
|
"@types/react": "^18.2.41",
|
|
42
43
|
"@types/react-native": "0.73.0",
|
|
43
|
-
"react-native-image-picker": "^7.1.2",
|
|
44
44
|
"react-native-image-crop-picker": "^0.41.2",
|
|
45
|
+
"react-native-image-picker": "^7.1.2",
|
|
45
46
|
"typescript": "^5.3.3"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"react-native-image-rotate": "^2.1.0"
|
|
46
50
|
}
|
|
47
51
|
}
|
package/src/FullDocScanner.tsx
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from 'react-native';
|
|
12
12
|
import { launchImageLibrary } from 'react-native-image-picker';
|
|
13
13
|
import ImageCropPicker from 'react-native-image-crop-picker';
|
|
14
|
+
import ImageRotate from 'react-native-image-rotate';
|
|
14
15
|
import { DocScanner } from './DocScanner';
|
|
15
16
|
import type { CapturedDocument } from './types';
|
|
16
17
|
import type {
|
|
@@ -440,53 +441,52 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
|
|
|
440
441
|
setFlashEnabled(prev => !prev);
|
|
441
442
|
}, []);
|
|
442
443
|
|
|
443
|
-
const handleRotateImage = useCallback((degrees: -90 | 90) => {
|
|
444
|
+
const handleRotateImage = useCallback(async (degrees: -90 | 90) => {
|
|
444
445
|
if (!croppedImageData) return;
|
|
445
446
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
447
|
+
try {
|
|
448
|
+
// UI 회전 상태 먼저 업데이트 (즉각 반응)
|
|
449
|
+
setRotationDegrees(prev => {
|
|
450
|
+
const newRotation = (prev + degrees + 360) % 360;
|
|
451
|
+
return newRotation;
|
|
452
|
+
});
|
|
451
453
|
|
|
452
|
-
|
|
453
|
-
if (!croppedImageData) return;
|
|
454
|
+
console.log('[FullDocScanner] Starting image rotation...');
|
|
454
455
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
mediaType: 'photo',
|
|
461
|
-
cropping: true,
|
|
462
|
-
freeStyleCropEnabled: true,
|
|
463
|
-
includeBase64: true,
|
|
464
|
-
compressImageQuality: 0.9,
|
|
465
|
-
cropperToolbarTitle: ' ',
|
|
466
|
-
cropperChooseText: '완료',
|
|
467
|
-
cropperCancelText: '취소',
|
|
468
|
-
cropperRotateButtonsHidden: false,
|
|
469
|
-
});
|
|
456
|
+
// ImageRotate를 사용해서 실제로 이미지 회전 (UI 없이)
|
|
457
|
+
const rotatedImagePath = await ImageRotate.rotateImage(
|
|
458
|
+
croppedImageData.path,
|
|
459
|
+
degrees,
|
|
460
|
+
);
|
|
470
461
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
462
|
+
console.log('[FullDocScanner] Image rotated successfully:', rotatedImagePath);
|
|
463
|
+
|
|
464
|
+
// 회전된 이미지로 교체
|
|
465
|
+
setCroppedImageData({
|
|
466
|
+
path: rotatedImagePath,
|
|
467
|
+
base64: undefined, // base64는 다시 읽어야 함
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
// rotation degrees는 0으로 리셋 (이미 실제 파일에 적용되었으므로)
|
|
471
|
+
setRotationDegrees(0);
|
|
472
|
+
} catch (error) {
|
|
473
|
+
console.error('[FullDocScanner] Image rotation error:', error);
|
|
474
|
+
// 에러 발생 시 UI rotation 원복
|
|
475
|
+
setRotationDegrees(prev => {
|
|
476
|
+
const revertRotation = (prev - degrees + 360) % 360;
|
|
477
|
+
return revertRotation;
|
|
487
478
|
});
|
|
488
479
|
}
|
|
489
|
-
}, [croppedImageData
|
|
480
|
+
}, [croppedImageData]);
|
|
481
|
+
|
|
482
|
+
const handleConfirm = useCallback(() => {
|
|
483
|
+
if (!croppedImageData) return;
|
|
484
|
+
|
|
485
|
+
onResult({
|
|
486
|
+
path: croppedImageData.path,
|
|
487
|
+
base64: croppedImageData.base64,
|
|
488
|
+
});
|
|
489
|
+
}, [croppedImageData, onResult]);
|
|
490
490
|
|
|
491
491
|
const handleRetake = useCallback(() => {
|
|
492
492
|
console.log('[FullDocScanner] Retake - clearing cropped image and resetting scanner');
|