Feature/convert to grayscale (#3003)

# Description of Changes

Please provide a summary of the changes, including:

- What was changed
  -Grayscale Image Compression:
Modified the compressImagesInPDF method to optionally convert images to
grayscale during compression. This is
achieved by checking if the grayScale flag is true (or if the image is
already in grayscale) and then processing the image
   accordingly.

   UI Update:
Updated the compress-pdf.html file by adding a checkbox for grayscale
compression. Additionally, a new translation
key compress.grayscale.label with the text "Apply Grayscale for
Compression" has been added across all supported
   languages. 
- Why the change was made
  -Enhanced Compression Options:
This feature provides users with an option to compress images in PDFs
more effectively by reducing the color complexity, which can lead to
smaller file sizes.

Improved Flexibility:
It allows users to decide whether they want to maintain the original
color images or opt for a grayscale version.
- Any challenges encountered
- The translation for compress.grayscale.label was generated using an
automated translator, so it might not be completely accurate and could
require further review.

Closes #2603

---

## 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/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/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/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/DeveloperGuide.md#6-testing)
for more details.
This commit is contained in:
Abdur Rahman 2025-02-23 04:38:07 +05:30 committed by Dario Ghunney Ware
parent 4c9e77ce63
commit cfc93b1deb
43 changed files with 78 additions and 7 deletions

View File

@ -31,6 +31,7 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.api.misc.OptimizePdfRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.GeneralUtils;
@ -51,7 +52,7 @@ public class CompressController {
this.pdfDocumentFactory = pdfDocumentFactory;
}
private void compressImagesInPDF(Path pdfFile, double initialScaleFactor) throws Exception {
private void compressImagesInPDF(Path pdfFile, double initialScaleFactor, boolean grayScale) throws Exception {
byte[] fileBytes = Files.readAllBytes(pdfFile);
try (PDDocument doc = Loader.loadPDF(fileBytes)) {
double scaleFactor = initialScaleFactor;
@ -76,11 +77,23 @@ public class CompressController {
bufferedImage.getScaledInstance(
newWidth, newHeight, Image.SCALE_SMOOTH);
BufferedImage scaledBufferedImage =
new BufferedImage(
newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
scaledBufferedImage.getGraphics().drawImage(scaledImage, 0, 0, null);
BufferedImage scaledBufferedImage;
if (grayScale
|| bufferedImage.getType() == BufferedImage.TYPE_BYTE_GRAY) {
scaledBufferedImage =
new BufferedImage(
newWidth, newHeight, BufferedImage.TYPE_BYTE_GRAY);
scaledBufferedImage
.getGraphics()
.drawImage(scaledImage, 0, 0, null);
} else {
scaledBufferedImage =
new BufferedImage(
newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
scaledBufferedImage
.getGraphics()
.drawImage(scaledImage, 0, 0, null);
}
ByteArrayOutputStream compressedImageStream =
new ByteArrayOutputStream();
ImageIO.write(scaledBufferedImage, "jpeg", compressedImageStream);
@ -139,6 +152,7 @@ public class CompressController {
}
boolean sizeMet = false;
boolean grayscaleEnabled = Boolean.TRUE.equals(request.getGrayscale());
while (!sizeMet && optimizeLevel <= 9) {
// Apply additional image compression for levels 6-9
@ -152,7 +166,7 @@ public class CompressController {
case 9 -> 0.5; // 60% of original size
default -> 1.0;
};
compressImagesInPDF(tempInputFile, scaleFactor);
compressImagesInPDF(tempInputFile, scaleFactor, grayscaleEnabled);
}
// Run QPDF optimization
@ -169,6 +183,7 @@ public class CompressController {
command.add("--compression-level=" + optimizeLevel);
command.add("--compress-streams=y");
command.add("--object-streams=generate");
command.add("--no-warn");
command.add(tempInputFile.toString());
command.add(tempOutputFile.toString());

View File

@ -29,4 +29,13 @@ public class OptimizePdfRequest extends PDFFile {
"Whether to normalize the PDF content for better compatibility. Default is false.",
defaultValue = "false")
private Boolean normalize = false;
@Schema(
description = "Whether to convert the PDF to grayscale. Default is false.",
defaultValue = "false")
private Boolean grayscale = false;
public Boolean getGrayscale() {
return grayscale;
}
}

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=تطبيق التدرج الرمادي للضغط

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Sıxma üçün Boz Rəng Tətbiq Edin

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Версия
validateSignature.cert.keyUsage=Предназначение на ключа за използване
validateSignature.cert.selfSigned=Самостоятелно подписан
validateSignature.cert.bits=битове
compress.grayscale.label=Приложи сива скала за компресиране

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Aplicar escala de grisos per a la compressió

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Verze
validateSignature.cert.keyUsage=Použití klíče
validateSignature.cert.selfSigned=Podepsaný sám sebou
validateSignature.cert.bits=bitů
compress.grayscale.label=Použít stupnici šedi pro kompresi

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Anvend gråskala til komprimering

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Schlüsselverwendung
validateSignature.cert.selfSigned=Selbstsigniert
validateSignature.cert.bits=bits
compress.grayscale.label=Graustufen für Komprimierung anwenden

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Έκδοση
validateSignature.cert.keyUsage=Χρήση κλειδιού
validateSignature.cert.selfSigned=Αυτο-υπογεγραμμένο
validateSignature.cert.bits=bits
compress.grayscale.label=Εφαρμογή κλίμακας του γκρι για συμπίεση

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Apply Grayscale for Compression

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Apply Grayscale for Compression

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Aplicar escala de grises para compresión

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Aplikatu grisezko eskala konpresiorako

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=نسخه
validateSignature.cert.keyUsage=کاربرد کلید
validateSignature.cert.selfSigned=با امضای خود
validateSignature.cert.bits=بیت‌ها
compress.grayscale.label=اعمال مقیاس خاکستری برای فشرده‌سازی

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Usage de la clé
validateSignature.cert.selfSigned=Auto-signé
validateSignature.cert.bits=bits
compress.grayscale.label=Appliquer l'échelle de gris pour la compression

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Leagan
validateSignature.cert.keyUsage=Úsáid Eochrach
validateSignature.cert.selfSigned=Féin-Sínithe
validateSignature.cert.bits=giotáin
compress.grayscale.label=Cuir Scála Liath i bhFeidhm le Comhbhrú

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=संस्करण
validateSignature.cert.keyUsage=कुंजी उपयोग
validateSignature.cert.selfSigned=स्व-हस्ताक्षरित
validateSignature.cert.bits=बिट्स
compress.grayscale.label=संपीड़न के लिए ग्रेस्केल लागू करें

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Primijeni sivinu za kompresiju

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Verzió
validateSignature.cert.keyUsage=Kulcshasználat
validateSignature.cert.selfSigned=Önaláírt
validateSignature.cert.bits=bit
compress.grayscale.label=Szürkeárnyalatok alkalmazása tömörítéshez

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Terapkan Skala Abu-Abu untuk Kompresi

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Versione
validateSignature.cert.keyUsage=Utilizzo della chiave
validateSignature.cert.selfSigned=Autofirmato
validateSignature.cert.bits=bit
compress.grayscale.label=Applica scala di grigio per la compressione

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=バージョン
validateSignature.cert.keyUsage=キーの使用法
validateSignature.cert.selfSigned=自己署名
validateSignature.cert.bits=ビット
compress.grayscale.label=圧縮にグレースケールを適用する

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=버전
validateSignature.cert.keyUsage=키 용도
validateSignature.cert.selfSigned=자체 서명
validateSignature.cert.bits=비트
compress.grayscale.label=압축을 위해 그레이스케일 적용

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Grijsschaal toepassen voor compressie

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Bruk gråskala for komprimering

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Zastosuj skalę szarości do kompresji

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Versão
validateSignature.cert.keyUsage=Uso da chave
validateSignature.cert.selfSigned=Autoassinados
validateSignature.cert.bits=bits
compress.grayscale.label=Aplicar escala de cinza para compressão

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Versão
validateSignature.cert.keyUsage=Utilização da Chave
validateSignature.cert.selfSigned=Auto-Assinado
validateSignature.cert.bits=bits
compress.grayscale.label=Aplicar escala de cinzentos para compressão

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Aplicare scală de gri pentru compresie

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Версия
validateSignature.cert.keyUsage=Использование ключа
validateSignature.cert.selfSigned=Самоподписанный
validateSignature.cert.bits=бит
compress.grayscale.label=Применить шкалу серого для сжатия

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Použiť odtiene šedej na kompresiu

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Različica
validateSignature.cert.keyUsage=Uporaba ključa
validateSignature.cert.selfSigned=Samopodpisano
validateSignature.cert.bits=bits
compress.grayscale.label=Uporabi sivinsko lestvico za stiskanje

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Primeni sivinu za kompresiju

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Tillämpa gråskala för komprimering

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=ใช้ระดับสีเทาสำหรับการบีบอัด

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Sıkıştırma için Gri Ton Uygula

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Застосувати відтінки сірого для стиснення

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=Version
validateSignature.cert.keyUsage=Key Usage
validateSignature.cert.selfSigned=Self-Signed
validateSignature.cert.bits=bits
compress.grayscale.label=Áp dụng thang độ xám để nén

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=པར་གཞི།
validateSignature.cert.keyUsage=ལྡེ་མིག་བེད་སྤྱོད།
validateSignature.cert.selfSigned=རང་མིང་རྟགས།
validateSignature.cert.bits=གནས།
compress.grayscale.label=应用灰度进行压缩

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=版本
validateSignature.cert.keyUsage=密钥用途
validateSignature.cert.selfSigned=自签名
validateSignature.cert.bits=比特
compress.grayscale.label=应用灰度进行压缩

View File

@ -1384,3 +1384,4 @@ validateSignature.cert.version=版本
validateSignature.cert.keyUsage=金鑰用途
validateSignature.cert.selfSigned=自我簽署
validateSignature.cert.bits=位元
compress.grayscale.label=應用灰階進行壓縮

View File

@ -39,6 +39,13 @@
<option value="8">8</option>
<option value="9">9</option>
</select>
<div class="form-check mt-3">
<input class="form-check-input" type="checkbox" name="grayscale" id="grayscaleCheck" value="true">
<label class="form-check-label" for="grayscaleCheck" th:text="#{compress.grayscale.label}">
Convert images to grayscale for better compression
</label>
</div>
</div>
</div>
<div class="card mb-3">