diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java b/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java index 8a2a67c0a8..b3eec2b11e 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java @@ -1,21 +1,14 @@ package stirling.software.SPDF.controller.api.security; import java.awt.Color; -import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.List; import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; -import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode; import org.apache.pdfbox.pdmodel.common.PDRectangle; -import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory; -import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; -import org.apache.pdfbox.rendering.ImageType; -import org.apache.pdfbox.rendering.PDFRenderer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.ResponseEntity; @@ -32,6 +25,7 @@ import stirling.software.SPDF.model.PDFText; import stirling.software.SPDF.model.api.security.RedactPdfRequest; import stirling.software.SPDF.pdf.TextFinder; +import stirling.software.SPDF.utils.PdfUtils; import stirling.software.SPDF.utils.WebResponseUtils; @RestController @@ -81,22 +75,9 @@ public ResponseEntity redactPdf(@ModelAttribute RedactPdfRequest request } if (convertPDFToImage) { - PDDocument imageDocument = new PDDocument(); - PDFRenderer pdfRenderer = new PDFRenderer(document); - pdfRenderer.setSubsamplingAllowed(true); - for (int page = 0; page < document.getNumberOfPages(); ++page) { - BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB); - PDPage newPage = new PDPage(new PDRectangle(bim.getWidth(), bim.getHeight())); - imageDocument.addPage(newPage); - PDImageXObject pdImage = LosslessFactory.createFromImage(imageDocument, bim); - PDPageContentStream contentStream = - new PDPageContentStream( - imageDocument, newPage, AppendMode.APPEND, true, true); - contentStream.drawImage(pdImage, 0, 0); - contentStream.close(); - } + PDDocument convertedPdf = PdfUtils.convertPdfToPdfImage(document); document.close(); - document = imageDocument; + document = convertedPdf; } ByteArrayOutputStream baos = new ByteArrayOutputStream(); diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java b/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java index 2133ae2673..0b36cd5e02 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java @@ -36,6 +36,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import stirling.software.SPDF.model.api.security.AddWatermarkRequest; +import stirling.software.SPDF.utils.PdfUtils; import stirling.software.SPDF.utils.WebResponseUtils; @RestController @@ -60,6 +61,7 @@ public ResponseEntity addWatermark(@ModelAttribute AddWatermarkRequest r float opacity = request.getOpacity(); int widthSpacer = request.getWidthSpacer(); int heightSpacer = request.getHeightSpacer(); + boolean convertPdfToImage = request.isConvertPDFToImage(); // Load the input PDF PDDocument document = Loader.loadPDF(pdfFile.getBytes()); @@ -104,6 +106,12 @@ public ResponseEntity addWatermark(@ModelAttribute AddWatermarkRequest r contentStream.close(); } + if (convertPdfToImage) { + PDDocument convertedPdf = PdfUtils.convertPdfToPdfImage(document); + document.close(); + document = convertedPdf; + } + return WebResponseUtils.pdfDocToWebResponse( document, Filenames.toSimpleFileName(pdfFile.getOriginalFilename()) diff --git a/src/main/java/stirling/software/SPDF/model/api/security/AddWatermarkRequest.java b/src/main/java/stirling/software/SPDF/model/api/security/AddWatermarkRequest.java index 861568bf8e..1f080fd2a8 100644 --- a/src/main/java/stirling/software/SPDF/model/api/security/AddWatermarkRequest.java +++ b/src/main/java/stirling/software/SPDF/model/api/security/AddWatermarkRequest.java @@ -44,4 +44,7 @@ public class AddWatermarkRequest extends PDFFile { @Schema(description = "The height spacer between watermark elements", example = "50") private int heightSpacer; + + @Schema(description = "Convert the redacted PDF to an image", defaultValue = "false") + private boolean convertPDFToImage; } diff --git a/src/main/java/stirling/software/SPDF/utils/PdfUtils.java b/src/main/java/stirling/software/SPDF/utils/PdfUtils.java index 91cbb5cd41..c158990295 100644 --- a/src/main/java/stirling/software/SPDF/utils/PdfUtils.java +++ b/src/main/java/stirling/software/SPDF/utils/PdfUtils.java @@ -341,6 +341,30 @@ public static byte[] convertFromPdf( } } + /** + * Converts a given Pdf file to PDF-Image. + * + * @param document to be converted. Note: the caller is responsible for closing the document + * @return converted document to PDF-Image + * @throws IOException if conversion fails + */ + public static PDDocument convertPdfToPdfImage(PDDocument document) throws IOException { + PDDocument imageDocument = new PDDocument(); + PDFRenderer pdfRenderer = new PDFRenderer(document); + pdfRenderer.setSubsamplingAllowed(true); + for (int page = 0; page < document.getNumberOfPages(); ++page) { + BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB); + PDPage newPage = new PDPage(new PDRectangle(bim.getWidth(), bim.getHeight())); + imageDocument.addPage(newPage); + PDImageXObject pdImage = LosslessFactory.createFromImage(imageDocument, bim); + PDPageContentStream contentStream = + new PDPageContentStream(imageDocument, newPage, AppendMode.APPEND, true, true); + contentStream.drawImage(pdImage, 0, 0); + contentStream.close(); + } + return imageDocument; + } + private static BufferedImage prepareImageForPdfToImage( int maxWidth, int height, String imageType) { BufferedImage combined; diff --git a/src/main/resources/messages_en_GB.properties b/src/main/resources/messages_en_GB.properties index 79067b5489..f6f77624b8 100644 --- a/src/main/resources/messages_en_GB.properties +++ b/src/main/resources/messages_en_GB.properties @@ -945,6 +945,7 @@ watermark.selectText.6=heightSpacer (Space between each watermark vertically): watermark.selectText.7=Opacity (0% - 100%): watermark.selectText.8=Watermark Type: watermark.selectText.9=Watermark Image: +watermark.selectText.10=Convert PDF to PDF-Image watermark.submit=Add Watermark watermark.type.1=Text watermark.type.2=Image diff --git a/src/main/resources/messages_en_US.properties b/src/main/resources/messages_en_US.properties index 1f38bf8c01..b90bef0900 100644 --- a/src/main/resources/messages_en_US.properties +++ b/src/main/resources/messages_en_US.properties @@ -945,6 +945,7 @@ watermark.selectText.6=heightSpacer (Space between each watermark vertically): watermark.selectText.7=Opacity (0% - 100%): watermark.selectText.8=Watermark Type: watermark.selectText.9=Watermark Image: +watermark.selectText.10=Convert PDF to PDF-Image watermark.submit=Add Watermark watermark.type.1=Text watermark.type.2=Image diff --git a/src/main/resources/templates/security/add-watermark.html b/src/main/resources/templates/security/add-watermark.html index 71c323746d..2b78709f24 100644 --- a/src/main/resources/templates/security/add-watermark.html +++ b/src/main/resources/templates/security/add-watermark.html @@ -104,6 +104,10 @@ +
+ + +