Convert extract-image-scans to React component (#4505)

Co-authored-by: Claude <[email protected]>
This commit is contained in:
Anthony Stirling
2025-09-26 12:38:10 +01:00
committed by GitHub
co-authored by Claude
parent d613a4659e
commit 233b710b78
9 changed files with 442 additions and 15 deletions
@@ -0,0 +1,74 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { NumberInput, Stack } from '@mantine/core';
import { ScannerImageSplitParameters } from '../../../hooks/tools/scannerImageSplit/useScannerImageSplitParameters';
interface ScannerImageSplitSettingsProps {
parameters: ScannerImageSplitParameters;
onParameterChange: <K extends keyof ScannerImageSplitParameters>(key: K, value: ScannerImageSplitParameters[K]) => void;
disabled?: boolean;
}
const ScannerImageSplitSettings: React.FC<ScannerImageSplitSettingsProps> = ({
parameters,
onParameterChange,
disabled = false
}) => {
const { t } = useTranslation();
return (
<Stack gap="md">
<NumberInput
label={t('ScannerImageSplit.selectText.1', 'Angle Threshold:')}
description={t('ScannerImageSplit.selectText.2', 'Sets the minimum absolute angle required for the image to be rotated (default: 10).')}
value={parameters.angle_threshold}
onChange={(value) => onParameterChange('angle_threshold', Number(value) || 10)}
min={0}
step={1}
disabled={disabled}
/>
<NumberInput
label={t('ScannerImageSplit.selectText.3', 'Tolerance:')}
description={t('ScannerImageSplit.selectText.4', 'Determines the range of colour variation around the estimated background colour (default: 30).')}
value={parameters.tolerance}
onChange={(value) => onParameterChange('tolerance', Number(value) || 30)}
min={0}
step={1}
disabled={disabled}
/>
<NumberInput
label={t('ScannerImageSplit.selectText.5', 'Minimum Area:')}
description={t('ScannerImageSplit.selectText.6', 'Sets the minimum area threshold for a photo (default: 10000).')}
value={parameters.min_area}
onChange={(value) => onParameterChange('min_area', Number(value) || 10000)}
min={0}
step={100}
disabled={disabled}
/>
<NumberInput
label={t('ScannerImageSplit.selectText.7', 'Minimum Contour Area:')}
description={t('ScannerImageSplit.selectText.8', 'Sets the minimum contour area threshold for a photo.')}
value={parameters.min_contour_area}
onChange={(value) => onParameterChange('min_contour_area', Number(value) || 500)}
min={0}
step={10}
disabled={disabled}
/>
<NumberInput
label={t('ScannerImageSplit.selectText.9', 'Border Size:')}
description={t('ScannerImageSplit.selectText.10', 'Sets the size of the border added and removed to prevent white borders in the output (default: 1).')}
value={parameters.border_size}
onChange={(value) => onParameterChange('border_size', Number(value) || 1)}
min={0}
step={1}
disabled={disabled}
/>
</Stack>
);
};
export default ScannerImageSplitSettings;
@@ -0,0 +1,54 @@
import { useTranslation } from 'react-i18next';
import { TooltipContent } from '../../types/tips';
export const useScannerImageSplitTips = (): TooltipContent => {
const { t } = useTranslation();
return {
header: {
title: t('scannerImageSplit.tooltip.title', 'Photo Splitter')
},
tips: [
{
title: t('scannerImageSplit.tooltip.whatThisDoes', 'What this does'),
description: t('scannerImageSplit.tooltip.whatThisDoesDesc',
'Automatically finds and extracts each photo from a scanned page or composite image—no manual cropping.'
)
},
{
title: t('scannerImageSplit.tooltip.whenToUse', 'When to use'),
bullets: [
t('scannerImageSplit.tooltip.useCase1', 'Scan whole album pages in one go'),
t('scannerImageSplit.tooltip.useCase2', 'Split flatbed batches into separate files'),
t('scannerImageSplit.tooltip.useCase3', 'Break collages into individual photos'),
t('scannerImageSplit.tooltip.useCase4', 'Pull photos from documents')
]
},
{
title: t('scannerImageSplit.tooltip.quickFixes', 'Quick fixes'),
bullets: [
t('scannerImageSplit.tooltip.problem1', 'Photos not detected → increase Tolerance to 3050'),
t('scannerImageSplit.tooltip.problem2', 'Too many false detections → increase Minimum Area to 15,00020,000'),
t('scannerImageSplit.tooltip.problem3', 'Crops are too tight → increase Border Size to 510'),
t('scannerImageSplit.tooltip.problem4', 'Tilted photos not straightened → lower Angle Threshold to ~5°'),
t('scannerImageSplit.tooltip.problem5', 'Dust/noise boxes → increase Minimum Contour Area to 10002000')
]
},
{
title: t('scannerImageSplit.tooltip.setupTips', 'Setup tips'),
bullets: [
t('scannerImageSplit.tooltip.tip1', 'Use a plain, light background'),
t('scannerImageSplit.tooltip.tip2', 'Leave a small gap (≈1 cm) between photos'),
t('scannerImageSplit.tooltip.tip3', 'Scan at 300600 DPI'),
t('scannerImageSplit.tooltip.tip4', 'Clean the scanner glass')
]
},
{
title: t('scannerImageSplit.tooltip.headsUp', 'Heads-up'),
description: t('scannerImageSplit.tooltip.headsUpDesc',
'Overlapping photos or backgrounds very close in colour to the photos can reduce accuracy—try a lighter or darker background and leave more space.'
)
}
]
};
};