From d44b9666aeb362ab037f0321ae20a009ed23f504 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Sat, 11 Feb 2023 00:37:53 +0000 Subject: [PATCH] changes! --- .../SPDF/controller/ContrastController.java | 29 ++++ .../converters/ConvertImgPDFController.java | 7 +- .../security/MetadataController.java | 97 +++++++++-- .../software/SPDF/utils/PdfUtils.java | 13 +- src/main/resources/messages_en_GB.properties | 2 - src/main/resources/static/images/docker.svg | 2 +- src/main/resources/static/images/github.svg | 2 +- .../resources/templates/adjust-contrast.html | 36 ++++ .../templates/convert/pdf-to-img.html | 12 +- .../templates/security/change-metadata.html | 157 ++++++++++-------- 10 files changed, 245 insertions(+), 112 deletions(-) create mode 100644 src/main/java/stirling/software/SPDF/controller/ContrastController.java create mode 100644 src/main/resources/templates/adjust-contrast.html diff --git a/src/main/java/stirling/software/SPDF/controller/ContrastController.java b/src/main/java/stirling/software/SPDF/controller/ContrastController.java new file mode 100644 index 000000000..5485fb610 --- /dev/null +++ b/src/main/java/stirling/software/SPDF/controller/ContrastController.java @@ -0,0 +1,29 @@ +package stirling.software.SPDF.controller; + +import java.io.IOException; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +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 stirling.software.SPDF.utils.PdfUtils; + +@Controller +public class ContrastController { + + @GetMapping("/adjust-contrast") + public String adjustContrastMain(Model model) { + model.addAttribute("currentPage", "adjustContrast"); + return "adjust-contrast"; + } + + + +} 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 e13db1bff..db0b2aa85 100644 --- a/src/main/java/stirling/software/SPDF/controller/converters/ConvertImgPDFController.java +++ b/src/main/java/stirling/software/SPDF/controller/converters/ConvertImgPDFController.java @@ -48,8 +48,7 @@ public class ConvertImgPDFController { @PostMapping("/pdf-to-img") public ResponseEntity convertToImage(@RequestParam("fileInput") MultipartFile file, @RequestParam("imageFormat") String imageFormat, - @RequestParam("singleOrMultiple") String singleOrMultiple, @RequestParam("colorType") String colorType, @RequestParam("dpi") String dpi, - @RequestParam("contrast") String contrast, @RequestParam("brightness") String brightness) throws IOException { + @RequestParam("singleOrMultiple") String singleOrMultiple, @RequestParam("colorType") String colorType, @RequestParam("dpi") String dpi) throws IOException { byte[] pdfBytes = file.getBytes(); ImageType colorTypeResult = ImageType.RGB; @@ -62,9 +61,7 @@ public class ConvertImgPDFController { boolean singleImage = singleOrMultiple.equals("single"); byte[] result = null; try { - result = PdfUtils.convertFromPdf(pdfBytes, imageFormat.toLowerCase(), colorTypeResult, singleImage, Integer.valueOf(dpi), Integer.valueOf(contrast), - Integer.valueOf(brightness)); // DPI, contrast, - // brightness + result = PdfUtils.convertFromPdf(pdfBytes, imageFormat.toLowerCase(), colorTypeResult, singleImage, Integer.valueOf(dpi)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); 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 2c70428ea..aca292a5a 100644 --- a/src/main/java/stirling/software/SPDF/controller/security/MetadataController.java +++ b/src/main/java/stirling/software/SPDF/controller/security/MetadataController.java @@ -1,15 +1,23 @@ package stirling.software.SPDF.controller.security; import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; import java.util.Map; import java.util.Map.Entry; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDDocumentInformation; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; 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 stirling.software.SPDF.utils.PdfUtils; @Controller public class MetadataController { @@ -21,14 +29,82 @@ public class MetadataController { } @PostMapping("/update-metadata") - public ResponseEntity metadata(@RequestParam Map allRequestParams) throws IOException { + public ResponseEntity metadata(@RequestParam("fileInput") MultipartFile pdfFile, + @RequestParam(value = "deleteAll", required = false, defaultValue = "false") Boolean deleteAll, + @RequestParam(value = "author", required = false) String author, + @RequestParam(value = "creationDate", required = false) String creationDate, + @RequestParam(value = "creator", required = false) String creator, + @RequestParam(value = "keywords", required = false) String keywords, + @RequestParam(value = "modificationDate", required = false) String modificationDate, + @RequestParam(value = "producer", required = false) String producer, + @RequestParam(value = "subject", required = false) String subject, + @RequestParam(value = "title", required = false) String title, + @RequestParam(value = "trapped", required = false) String trapped, + @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; - } + + PDDocument document = PDDocument.load(pdfFile.getBytes()); + + // Remove all metadata based on flag + PDDocumentInformation info = document.getDocumentInformation(); + + if(deleteAll) { + for (String key : info.getMetadataKeys()) { + info.setCustomMetadataValue(key, null); + } + } else { + if(author != null && author.length() > 0) { + info.setAuthor(author); + } + + if(creationDate != null && creationDate.length() > 0) { + Calendar creationDateCal = Calendar.getInstance(); + try { + creationDateCal.setTime(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(creationDate)); + } catch (ParseException e) { + e.printStackTrace(); + } + info.setCreationDate(creationDateCal); + } + if(creator != null && creator.length() > 0) { + info.setCreator(creator); + } + if(keywords != null && keywords.length() > 0) { + info.setKeywords(keywords); + } + if(modificationDate != null && modificationDate.length() > 0) { + Calendar modificationDateCal = Calendar.getInstance(); + try { + modificationDateCal.setTime(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(modificationDate)); + } catch (ParseException e) { + e.printStackTrace(); + } + info.setModificationDate(modificationDateCal); + } + if(producer != null && producer.length() > 0) { + info.setProducer(producer); + } + if(subject != null && subject.length() > 0) { + info.setSubject(subject); + } + if(title != null && title.length() > 0) { + info.setTitle(title); + } + if(trapped != null && trapped.length() > 0) { + info.setTrapped(trapped); + } + } + + + + + + return PdfUtils.pdfDocToWebResponse(document, pdfFile.getName() + "_metadata.pdf"); + } // @PostMapping("/update-metadata") // public ResponseEntity addWatermark(@RequestParam("fileInput") MultipartFile pdfFile, @@ -51,20 +127,7 @@ public class MetadataController { // 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 // for (PDPage page : document.getPages()) { diff --git a/src/main/java/stirling/software/SPDF/utils/PdfUtils.java b/src/main/java/stirling/software/SPDF/utils/PdfUtils.java index 1aaafe41c..eed2227d6 100644 --- a/src/main/java/stirling/software/SPDF/utils/PdfUtils.java +++ b/src/main/java/stirling/software/SPDF/utils/PdfUtils.java @@ -31,7 +31,7 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import com.spire.pdf.PdfDocument; - +//Generate tests for the below class public class PdfUtils { private static final Logger logger = LoggerFactory.getLogger(PdfUtils.class); @@ -79,7 +79,7 @@ public class PdfUtils { } } - public static byte[] convertFromPdf(byte[] inputStream, String imageType, ImageType colorType, boolean singleImage, int DPI, int contrast, int brightness) + public static byte[] convertFromPdf(byte[] inputStream, String imageType, ImageType colorType, boolean singleImage, int DPI) throws IOException, Exception { try (PDDocument document = PDDocument.load(new ByteArrayInputStream(inputStream))) { PDFRenderer pdfRenderer = new PDFRenderer(document); @@ -88,14 +88,9 @@ public class PdfUtils { // Create images of all pages for (int i = 0; i < pageCount; i++) { - BufferedImage image = pdfRenderer.renderImageWithDPI(i, 300, colorType); - float scale = contrast + 1f; - float offset = brightness; - RescaleOp rescaleOp = new RescaleOp(scale, offset, null); - BufferedImage dest = rescaleOp.filter(image, null); - images.add(dest); + images.add(pdfRenderer.renderImageWithDPI(i, 300, colorType)); } - + 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); diff --git a/src/main/resources/messages_en_GB.properties b/src/main/resources/messages_en_GB.properties index 2862f69ac..8cba9a7ed 100644 --- a/src/main/resources/messages_en_GB.properties +++ b/src/main/resources/messages_en_GB.properties @@ -131,8 +131,6 @@ pdfToImage.colorType=Colour type pdfToImage.color=Colour pdfToImage.grey=Greyscale pdfToImage.blackwhite=Black and White (May lose data!) -pdfToImage.contrast=Contrast Value: -pdfToImage.brightness=Brightness Value: pdfToImage.submit=Convert #addPassword diff --git a/src/main/resources/static/images/docker.svg b/src/main/resources/static/images/docker.svg index 385b8ef9b..7a761dd01 100644 --- a/src/main/resources/static/images/docker.svg +++ b/src/main/resources/static/images/docker.svg @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/src/main/resources/static/images/github.svg b/src/main/resources/static/images/github.svg index 618a342ea..c3d5f08ec 100644 --- a/src/main/resources/static/images/github.svg +++ b/src/main/resources/static/images/github.svg @@ -1,6 +1,6 @@ - + Github-color Created with Sketch. diff --git a/src/main/resources/templates/adjust-contrast.html b/src/main/resources/templates/adjust-contrast.html new file mode 100644 index 000000000..16b4b9611 --- /dev/null +++ b/src/main/resources/templates/adjust-contrast.html @@ -0,0 +1,36 @@ + + + + + + + + +
+
+
+

+
+
+
+

+
+

+
+
+ + +
+ +
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/convert/pdf-to-img.html b/src/main/resources/templates/convert/pdf-to-img.html index 4a122f33d..ef6c48ee1 100644 --- a/src/main/resources/templates/convert/pdf-to-img.html +++ b/src/main/resources/templates/convert/pdf-to-img.html @@ -39,19 +39,9 @@
- +
- -
- - -
- -
- - -
diff --git a/src/main/resources/templates/security/change-metadata.html b/src/main/resources/templates/security/change-metadata.html index f85f4952b..5a5e49d4d 100644 --- a/src/main/resources/templates/security/change-metadata.html +++ b/src/main/resources/templates/security/change-metadata.html @@ -13,66 +13,70 @@

-
+

Please select the variables you wish to change

-
- +
+
-
+
-
+
- +
-
+
- +
-
+
- +
-
+
- +
-
+
- +
-
+
- +
-
+
- +
-
+
- +
-
+
- +
@@ -87,25 +91,32 @@ const advancedMetadataDiv = document.getElementById('advancedMetadata'); const otherMetadataEntriesDiv = document.getElementById('otherMetadataEntries'); - - - - + const addMetadataBtn = document.getElementById("addMetadataBtn"); const customMetadataFormContainer = document.getElementById("customMetadataEntries"); - + var count = 1; addMetadataBtn.addEventListener("click", () => { const keyInput = document.createElement("input"); keyInput.type = "text"; keyInput.placeholder = "Key"; - + keyInput.className = "form-control"; + keyInput.name = "customKey" + count; + const valueInput = document.createElement("input"); valueInput.type = "text"; valueInput.placeholder = "Value"; - - customMetadataFormContainer.appendChild(keyInput); - customMetadataFormContainer.appendChild(valueInput); + valueInput.className = "form-control"; + valueInput.name = "customValue1" + count; + count = count + 1; + + const formGroup = document.createElement("div"); + formGroup.className = "form-group"; + formGroup.appendChild(keyInput); + formGroup.appendChild(valueInput); + + + customMetadataFormContainer.appendChild(formGroup); }); @@ -126,15 +137,15 @@ const file = this.files[0]; var url = URL.createObjectURL(file) - const pdf = await pdfjsLib.getDocument(url).promise; + const pdf = await pdfjsLib.getDocument(url).promise; const pdfMetadata = await pdf.getMetadata(); lastPDFFile = pdfMetadata?.info console.log(pdfMetadata); authorInput.value = pdfMetadata?.info?.Author; - creationDateInput.value = pdfMetadata?.info?.CreationDate; + creationDateInput.value = convertDateFormat(pdfMetadata?.info?.CreationDate); creatorInput.value = pdfMetadata?.info?.Creator; keywordsInput.value = pdfMetadata?.info?.Keywords; - modificationDateInput.value = pdfMetadata?.info?.ModDate; + modificationDateInput.value = convertDateFormat(pdfMetadata?.info?.ModDate); producerInput.value = pdfMetadata?.info?.Producer; subjectInput.value = pdfMetadata?.info?.Subject; titleInput.value = pdfMetadata?.info?.Title; @@ -142,39 +153,53 @@ addExtra(); }); + function convertDateFormat(dateTimeString) { + if (!dateTimeString || dateTimeString.length < 17) { + return dateTimeString; + } - function addExtra() { - const event = document.getElementById("advancedModeCheckbox"); - - - if (event.checked) { - advancedMetadataDiv.style.display = 'block'; - for (const [key, value] of Object.entries(lastPDFFile)) { - if (key === 'Author' || key === 'CreationDate' || key === 'Creator' || key === 'Keywords' || key === 'ModDate' || key === 'Producer' || key === 'Subject' || key === 'Title' || key === 'Trapped') { - continue; - } - const entryDiv = document.createElement('div'); - entryDiv.className = 'form-group'; - - - - entryDiv.innerHTML = `
`; - otherMetadataEntriesDiv.appendChild(entryDiv); - } - } else { - advancedMetadataDiv.style.display = 'none'; - while (otherMetadataEntriesDiv.firstChild) { - otherMetadataEntriesDiv.removeChild(otherMetadataEntriesDiv.firstChild); - } - } - - - } - + const year = dateTimeString.substring(2, 6); + const month = dateTimeString.substring(6, 8); + const day = dateTimeString.substring(8, 10); + const hour = dateTimeString.substring(10, 12); + const minute = dateTimeString.substring(12, 14); + const second = dateTimeString.substring(14, 16); + + return year + "/" + month + "/" + day + " " + hour + ":" + minute + ":" + second; + } + + function addExtra() { + const event = document.getElementById("advancedModeCheckbox"); + + + if (event.checked) { + advancedMetadataDiv.style.display = 'block'; + for (const [key, value] of Object.entries(lastPDFFile)) { + if (key === 'Author' || key === 'CreationDate' || key === 'Creator' || key === 'Keywords' || key === 'ModDate' || key === 'Producer' || key === 'Subject' || key === 'Title' || key === 'Trapped') { + continue; + } + const entryDiv = document.createElement('div'); + entryDiv.className = 'form-group'; + + + + entryDiv.innerHTML = `
`; + otherMetadataEntriesDiv.appendChild(entryDiv); + } + } else { + advancedMetadataDiv.style.display = 'none'; + while (otherMetadataEntriesDiv.firstChild) { + otherMetadataEntriesDiv.removeChild(otherMetadataEntriesDiv.firstChild); + } + } + + + } + advancedModeCheckbox.addEventListener('change', (event) => { - - addExtra(); - }); + + addExtra(); + });