diff --git a/src/main/java/stirling/software/SPDF/controller/converters/ConvertImgPDFController.java b/src/main/java/stirling/software/SPDF/controller/converters/ConvertImgPDFController.java index 5a943183c..765085a46 100644 --- a/src/main/java/stirling/software/SPDF/controller/converters/ConvertImgPDFController.java +++ b/src/main/java/stirling/software/SPDF/controller/converters/ConvertImgPDFController.java @@ -1,9 +1,13 @@ package stirling.software.SPDF.controller.converters; +import java.io.File; import java.io.IOException; +import org.apache.pdfbox.rendering.ImageType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -44,16 +48,41 @@ public class ConvertImgPDFController { } @PostMapping("/pdf-to-img") - public ResponseEntity convertToImage(@RequestParam("fileInput") MultipartFile file, - @RequestParam("imageFormat") String imageFormat) throws IOException { + public ResponseEntity convertToImage(@RequestParam("fileInput") MultipartFile file, + @RequestParam("imageFormat") String imageFormat, + @RequestParam("singleOrMultiple") String singleOrMultiple, + @RequestParam("colorType") String colorType) throws IOException { byte[] pdfBytes = file.getBytes(); + ImageType colorTypeResult = ImageType.RGB; + if("greyscale".equals(colorType)) { + colorTypeResult = ImageType.GRAY; + } else if ("blackwhite".equals(colorType)) { + colorTypeResult = ImageType.BINARY; + } // returns bytes for image - byte[] result = PdfUtils.convertFromPdf(pdfBytes, imageFormat.toLowerCase()); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.parseMediaType(getMediaType(imageFormat))); - headers.setCacheControl("must-revalidate, post-check=0, pre-check=0"); - ResponseEntity response = new ResponseEntity<>(result, headers, HttpStatus.OK); - return response; + boolean singleImage = singleOrMultiple.equals("single"); + byte[] result = null; + try { + result = PdfUtils.convertFromPdf(pdfBytes, imageFormat.toLowerCase(), colorTypeResult, singleImage); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if(singleImage) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.parseMediaType(getMediaType(imageFormat))); + headers.setCacheControl("must-revalidate, post-check=0, pre-check=0"); + ResponseEntity response = new ResponseEntity<>(new ByteArrayResource(result), headers, HttpStatus.OK); + return response; + } else { + ByteArrayResource resource = new ByteArrayResource(result); + // return the Resource in the response + return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=converted_documents.zip") + .contentType(MediaType.APPLICATION_OCTET_STREAM).contentLength(resource.contentLength()).body(resource); + } } private String getMediaType(String imageFormat) { diff --git a/src/main/java/stirling/software/SPDF/controller/security/MetadataController.java b/src/main/java/stirling/software/SPDF/controller/security/MetadataController.java index f2414d0d8..52358564d 100644 --- a/src/main/java/stirling/software/SPDF/controller/security/MetadataController.java +++ b/src/main/java/stirling/software/SPDF/controller/security/MetadataController.java @@ -3,6 +3,8 @@ package stirling.software.SPDF.controller.security; import java.awt.Color; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.Map; +import java.util.Map.Entry; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocumentInformation; @@ -19,11 +21,13 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; +import jakarta.servlet.http.HttpServletRequest; import stirling.software.SPDF.utils.PdfUtils; @Controller @@ -34,25 +38,55 @@ public class MetadataController { model.addAttribute("currentPage", "change-metadata"); return "security/change-metadata"; } - @PostMapping("/update-metadata") - public ResponseEntity addWatermark(@RequestParam("pdfFile") MultipartFile pdfFile, - @RequestParam("author") String author) throws IOException { - // Load the PDF file - PDDocument document = PDDocument.load(pdfFile.getBytes()); - - - // Remove all metadata based on flag - PDDocumentInformation info = document.getDocumentInformation(); - for (String key : info.getMetadataKeys()) { - info.setCustomMetadataValue(key, null); - } - - - - - return PdfUtils.pdfDocToWebResponse(document, pdfFile.getName() + "_metadata.pdf"); + public ResponseEntity metadata( + @RequestParam Map allRequestParams) throws IOException { + + System.out.println("1 allRequestParams.size() = " + allRequestParams.size()); + for(Entry entry : allRequestParams.entrySet()) { + System.out.println("1 key=" + entry.getKey() + ", value=" + entry.getValue()); + } + return null; } + + + + +// @PostMapping("/update-metadata") +// public ResponseEntity addWatermark(@RequestParam("fileInput") MultipartFile pdfFile, +// @RequestParam Map allRequestParams,HttpServletRequest request, ModelMap model) throws IOException { +// // Load the PDF file +// System.out.println("1 allRequestParams.size() = " + allRequestParams.size()); +// for(Entry entry : allRequestParams.entrySet()) { +// System.out.println("1 key=" + entry.getKey() + ", value=" + entry.getValue()); +// } +// +// +// System.out.println("request.getParameterMap().size() = " + request.getParameterMap().size()); +// for(Entry entry : request.getParameterMap().entrySet()) { +// System.out.println("2 key=" + entry.getKey() + ", value=" + entry.getValue()); +// } +// +// +// System.out.println("mdoel.size() = " + model.size()); +// for(Entry entry : model.entrySet()) { +// System.out.println("3 key=" + entry.getKey() + ", value=" + entry.getValue()); +// } +// +// PDDocument document = PDDocument.load(pdfFile.getBytes()); +// +// +// // Remove all metadata based on flag +// PDDocumentInformation info = document.getDocumentInformation(); +// for (String key : info.getMetadataKeys()) { +// info.setCustomMetadataValue(key, null); +// } +// +// +// +// +// return PdfUtils.pdfDocToWebResponse(document, pdfFile.getName() + "_metadata.pdf"); +// } // // Loop over all pages and remove annotations diff --git a/src/main/java/stirling/software/SPDF/utils/PdfUtils.java b/src/main/java/stirling/software/SPDF/utils/PdfUtils.java index 43c235d62..1b2de70c9 100644 --- a/src/main/java/stirling/software/SPDF/utils/PdfUtils.java +++ b/src/main/java/stirling/software/SPDF/utils/PdfUtils.java @@ -1,5 +1,6 @@ package stirling.software.SPDF.utils; +import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -7,19 +8,22 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.Iterator; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; -import javax.imageio.IIOImage; import javax.imageio.ImageIO; -import javax.imageio.ImageWriter; -import javax.imageio.stream.ImageOutputStream; - import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; 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.HttpHeaders; @@ -76,27 +80,55 @@ public class PdfUtils { } } - public static byte[] convertFromPdf(byte[] inputStream, String imageType) throws IOException { - try (PDDocument document = PDDocument.load(new ByteArrayInputStream(inputStream))) { - // Create a PDFRenderer to convert the PDF to an image - PDFRenderer pdfRenderer = new PDFRenderer(document); - BufferedImage bim = pdfRenderer.renderImageWithDPI(0, 300, ImageType.RGB); + public static byte[] convertFromPdf(byte[] inputStream, String imageType, ImageType colorType, boolean singleImage) throws IOException, Exception { + try (PDDocument document = PDDocument.load(new ByteArrayInputStream(inputStream))) { + PDFRenderer pdfRenderer = new PDFRenderer(document); + int pageCount = document.getNumberOfPages(); + List images = new ArrayList<>(); + // Create images of all pages + for (int i = 0; i < pageCount; i++) { + images.add(pdfRenderer.renderImageWithDPI(i, 300, colorType)); + } - // Get an ImageWriter for the specified image type - Iterator writers = ImageIO.getImageWritersByFormatName(imageType); - ImageWriter writer = writers.next(); + if (singleImage) { + // Combine all images into a single big image + BufferedImage combined = new BufferedImage(images.get(0).getWidth() , + images.get(0).getHeight()* pageCount, BufferedImage.TYPE_INT_RGB); + Graphics g = combined.getGraphics(); + for (int i = 0; i < images.size(); i++) { + g.drawImage(images.get(i), 0, i * images.get(0).getHeight(), null); + } + images = Arrays.asList(combined); + } - // Create a ByteArrayOutputStream to save the image to - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (ImageOutputStream ios = ImageIO.createImageOutputStream(baos)) { - writer.setOutput(ios); - // Write the image to the output stream - writer.write(new IIOImage(bim, null, null)); - // Log that the image was successfully written to the byte array - logger.info("Image successfully written to byte array"); - } - return baos.toByteArray(); - } catch (IOException e) { + + // Create a ByteArrayOutputStream to save the image(s) to + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + if (singleImage) { + // Write the image to the output stream + ImageIO.write(images.get(0), "PNG", baos); + + // Log that the image was successfully written to the byte array + logger.info("Image successfully written to byte array"); + } else { + // Zip the images and return as byte array + try (ZipOutputStream zos = new ZipOutputStream(baos)) { + for (int i = 0; i < images.size(); i++) { + BufferedImage image = images.get(i); + try (ByteArrayOutputStream baosImage = new ByteArrayOutputStream()) { + ImageIO.write(image, "PNG", baosImage); + + // Add the image to the zip file + zos.putNextEntry(new ZipEntry(String.format("page_%d.%s", i + 1, "png"))); + zos.write(baosImage.toByteArray()); + } + } + // Log that the images were successfully written to the byte array + logger.info("Images successfully written to byte array as a zip"); + } + } + return baos.toByteArray(); + } catch (IOException e) { // Log an error message if there is an issue converting the PDF to an image logger.error("Error converting PDF to image", e); throw e; diff --git a/src/main/resources/messages_ar_AR.properties b/src/main/resources/messages_ar_AR.properties index 50bda14e4..ed825a13e 100644 --- a/src/main/resources/messages_ar_AR.properties +++ b/src/main/resources/messages_ar_AR.properties @@ -129,6 +129,13 @@ imageToPDF.submit=تحول pdfToImage.title=تحويل PDF إلى صورة pdfToImage.header=تحويل PDF إلى صورة pdfToImage.selectText=تنسيق الصورة +pdfToImage.singleOrMultiple = \u0646\u0648\u0639 \u0646\u062A\u064A\u062C\u0629 \u0627\u0644\u0635\u0648\u0631\u0629 +pdfToImage.single = \u0635\u0648\u0631\u0629 \u0648\u0627\u062D\u062F\u0629 \u0643\u0628\u064A\u0631\u0629 +pdfToImage.multi = \u0635\u0648\u0631 \u0645\u062A\u0639\u062F\u062F\u0629 +pdfToImage.colorType = \u0646\u0648\u0639 \u0627\u0644\u0644\u0648\u0646 +pdfToImage.color = \u0627\u0644\u0644\u0648\u0646 +pdfToImage.grey = \u062A\u062F\u0631\u062C \u0627\u0644\u0631\u0645\u0627\u062F\u064A +pdfToImage.blackwhite = \u0623\u0628\u064A\u0636 \u0648\u0623\u0633\u0648\u062F (\u0642\u062F \u064A\u0641\u0642\u062F \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A!) pdfToImage.submit=تحول #addPassword diff --git a/src/main/resources/messages_de_DE.properties b/src/main/resources/messages_de_DE.properties index b5ce3c9d4..a8d092779 100644 --- a/src/main/resources/messages_de_DE.properties +++ b/src/main/resources/messages_de_DE.properties @@ -126,6 +126,13 @@ imageToPDF.submit=Umwandeln pdfToImage.title=PDF zu Bild pdfToImage.header=PDF zu Bild pdfToImage.selectText=Bildformat +pdfToImage.singleOrMultiple=Bildergebnistyp +pdfToImage.single=Einzelnes großes Bild +pdfToImage.multi=Mehrere Bilder +pdfToImage.colorType=Farbtyp +pdfToImage.color=Farbe +pdfToImage.grey=Graustufen +pdfToImage.blackwhite=Schwarzweiß (Datenverlust möglich!) pdfToImage.submit=Umwandeln #addPassword diff --git a/src/main/resources/messages_en_GB.properties b/src/main/resources/messages_en_GB.properties index 2c065d085..afd3bdb06 100644 --- a/src/main/resources/messages_en_GB.properties +++ b/src/main/resources/messages_en_GB.properties @@ -124,6 +124,13 @@ imageToPDF.submit=Convert pdfToImage.title=PDF to Image pdfToImage.header=PDF to Image pdfToImage.selectText=Image Format +pdfToImage.singleOrMultiple=Image result type +pdfToImage.single=Single Big Image +pdfToImage.multi=Multiple Images +pdfToImage.colorType=Colour type +pdfToImage.color=Colour +pdfToImage.grey=Greyscale +pdfToImage.blackwhite=Black and White (May lose data!) pdfToImage.submit=Convert #addPassword diff --git a/src/main/resources/messages_en_US.properties b/src/main/resources/messages_en_US.properties index 0e149c1ec..f285a1e07 100644 --- a/src/main/resources/messages_en_US.properties +++ b/src/main/resources/messages_en_US.properties @@ -127,8 +127,16 @@ imageToPDF.submit=Convert pdfToImage.title=PDF to Image pdfToImage.header=PDF to Image pdfToImage.selectText=Image Format +pdfToImage.singleOrMultiple=Image result type +pdfToImage.single=Single Big Image +pdfToImage.multi=Multiple Images +pdfToImage.colorType=Color type +pdfToImage.color=Color +pdfToImage.grey=Grayscale +pdfToImage.blackwhite=Black and White (May lose data!) pdfToImage.submit=Convert + #addPassword addPassword.title=Add Password addPassword.header=Add password (Encrypt) diff --git a/src/main/resources/messages_fr_FR.properties b/src/main/resources/messages_fr_FR.properties index a5089e320..6ab046bda 100644 --- a/src/main/resources/messages_fr_FR.properties +++ b/src/main/resources/messages_fr_FR.properties @@ -129,6 +129,13 @@ imageToPDF.submit=Convertir pdfToImage.title=PDF vers image pdfToImage.header=PDF vers image pdfToImage.selectText=Format d'image +pdfToImage.singleOrMultiple=Type de résultat d'image +pdfToImage.single=Une seule grande image +pdfToImage.multi=Plusieurs images +pdfToImage.colorType=Type de couleur +pdfToImage.color=Couleur +pdfToImage.grey=Niveaux de gris +pdfToImage.blackwhite=Noir et Blanc (Peut perdre des données !) pdfToImage.submit=Convertir #addPassword diff --git a/src/main/resources/templates/convert/pdf-to-img.html b/src/main/resources/templates/convert/pdf-to-img.html index 54f052fe7..5bfa543af 100644 --- a/src/main/resources/templates/convert/pdf-to-img.html +++ b/src/main/resources/templates/convert/pdf-to-img.html @@ -14,24 +14,39 @@

+

+
+ + +
+
+ + +
- + +
diff --git a/src/main/resources/templates/security/change-metadata.html b/src/main/resources/templates/security/change-metadata.html index 3ceb088b2..c61d04728 100644 --- a/src/main/resources/templates/security/change-metadata.html +++ b/src/main/resources/templates/security/change-metadata.html @@ -14,25 +14,21 @@

-
- - -
+

Please select the variables you wish to change

- -
- + +
+
-
- - +
+ +
-
@@ -69,12 +65,12 @@
- +
- +
- +

- +