[V2] feat(sign): add automatic white background removal for signature images (#5210)

# Description of Changes



This pull request adds a new feature that allows users to automatically
remove the white background from uploaded signature images, making them
transparent. The changes include UI improvements for image uploading,
new image processing utilities, and updates to translation files for
better user feedback.

### Image Upload & Processing Enhancements

* Added a `removeWhiteBackground` utility function in
`imageTransparency.ts` to process images and remove white backgrounds,
with options for automatic corner color detection and tolerance
settings.
* Updated the `ImageUploader` component to support background removal,
including a checkbox for toggling the feature, processing state
feedback, and integration with the new utility

### Signature Tool Integration

* Modified `SignSettings.tsx` to enable the background removal feature
for signature images, handle processed image data, and ensure signature
placement logic works seamlessly with the new feature.

### UI & Localization Updates

* Added new translation strings for background removal and image
processing feedback in the English locale file.



https://github.com/user-attachments/assets/28263940-1756-4f0e-9bfb-5603a6fb8a2c


<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [X] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [X] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [X] I have performed a self-review of my own code
- [X] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [X] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.

---------

Signed-off-by: Balázs Szücs <[email protected]>
This commit is contained in:
Balázs Szücs
2025-12-26 23:50:21 +00:00
committed by GitHub
parent 429520d3f9
commit 98fa5dfcc1
4 changed files with 236 additions and 21 deletions
@@ -461,23 +461,13 @@ const SignSettings = ({
const handleImageChange = async (file: File | null) => {
if (file && !disabled) {
try {
const result = await new Promise<string>((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => {
if (e.target?.result) {
resolve(e.target.result as string);
} else {
reject(new Error('Failed to read file'));
}
};
reader.onerror = () => reject(reader.error);
reader.readAsDataURL(file);
});
// Reset pause state and directly activate placement
setPlacementManuallyPaused(false);
lastAppliedPlacementKey.current = null;
setImageSignatureData(result);
// Image data will be set by onProcessedImageData callback in ImageUploader
// This avoids the race condition where both handleImageChange and onProcessedImageData
// try to set the image data, potentially with the wrong version
// Directly activate placement on image upload
if (typeof window !== 'undefined') {
@@ -491,8 +481,6 @@ const SignSettings = ({
} else if (!file) {
setImageSignatureData(undefined);
onDeactivateSignature?.();
setImageSignatureData(undefined);
onDeactivateSignature?.();
}
};
@@ -835,6 +823,12 @@ const SignSettings = ({
<ImageUploader
onImageChange={handleImageChange}
disabled={disabled}
allowBackgroundRemoval={true}
onProcessedImageData={(dataUrl) => {
if (dataUrl) {
setImageSignatureData(dataUrl);
}
}}
/>
{renderSaveButtonRow('image', hasImageSignature, handleSaveImageSignature)}
</Stack>