From cd4bd2a796983fab715a30408e6f9026137d2178 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Sun, 29 Jan 2023 17:06:53 +0000 Subject: [PATCH] Add rotate and compress (#7) * Add files via upload * Update build.gradle * Update general.css --- build.gradle | 8 +- .../SPDF/controller/CompressController.java | 87 ++++++++ .../SPDF/controller/ConvertPDFController.java | 45 +++++ .../SPDF/controller/FromPDFController.java | 6 +- .../controller/OverlayImageController.java | 4 +- .../SPDF/controller/PdfController.java | 4 +- .../RearrangePagesPDFController.java | 1 + .../SPDF/controller/RotationController.java | 74 +++++++ .../SPDF/controller/SplitPDFController.java | 4 +- src/main/resources/static/general.css | 2 +- .../resources/templates/compress-pdf.html | 43 ++++ src/main/resources/templates/convert-pdf.html | 61 ++++++ src/main/resources/templates/home.html | 190 ++++++++++-------- src/main/resources/templates/navbar.html | 26 +-- src/main/resources/templates/rotate-pdf.html | 47 +++++ 15 files changed, 496 insertions(+), 106 deletions(-) create mode 100644 src/main/java/stirling/software/SPDF/controller/CompressController.java create mode 100644 src/main/java/stirling/software/SPDF/controller/ConvertPDFController.java create mode 100644 src/main/java/stirling/software/SPDF/controller/RotationController.java create mode 100644 src/main/resources/templates/compress-pdf.html create mode 100644 src/main/resources/templates/convert-pdf.html create mode 100644 src/main/resources/templates/rotate-pdf.html diff --git a/build.gradle b/build.gradle index c2e5f251..2b893b67 100644 --- a/build.gradle +++ b/build.gradle @@ -5,11 +5,15 @@ plugins { } group = 'stirling.software' -version = '0.1.0' +version = '0.2.0' sourceCompatibility = '17' repositories { mavenCentral() + maven { + url "https://repo.e-iceblue.com/nexus/content/groups/public/" + name "com.e-iceblue" + } } dependencies { @@ -18,6 +22,7 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation 'org.apache.pdfbox:pdfbox:2.0.27' implementation 'org.apache.logging.log4j:log4j-core:2.19.0' + implementation 'e-iceblue:spire.pdf.free:5.1.0' } jar { @@ -27,6 +32,7 @@ jar { tasks.named('test') { useJUnitPlatform() } + task printVersion { println project.version } diff --git a/src/main/java/stirling/software/SPDF/controller/CompressController.java b/src/main/java/stirling/software/SPDF/controller/CompressController.java new file mode 100644 index 00000000..bffd19f0 --- /dev/null +++ b/src/main/java/stirling/software/SPDF/controller/CompressController.java @@ -0,0 +1,87 @@ +package stirling.software.SPDF.controller; + +import java.io.ByteArrayOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +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 com.spire.pdf.PdfCompressionLevel; +import com.spire.pdf.PdfDocument; +import com.spire.pdf.PdfPageBase; +import com.spire.pdf.exporting.PdfImageInfo; +import com.spire.pdf.graphics.PdfBitmap; + +import stirling.software.SPDF.utils.PdfUtils; +//import com.spire.pdf.*; +@Controller +public class CompressController { + + private static final Logger logger = LoggerFactory.getLogger(CompressController.class); + + @GetMapping("/compress-pdf") + public String compressPdfForm(Model model) { + model.addAttribute("currentPage", "compress-pdf"); + return "compress-pdf"; + } + + @PostMapping("/compress-pdf") + public ResponseEntity compressPDF(@RequestParam("fileInput") MultipartFile pdfFile, + @RequestParam("imageCompressionLevel") String imageCompressionLevel) throws IOException { + + + //Load a sample PDF document + PdfDocument document = new PdfDocument(); + document.loadFromBytes(pdfFile.getBytes()); + + //Compress PDF + document.getFileInfo().setIncrementalUpdate(false); + document.setCompressionLevel(PdfCompressionLevel.Best); + + //compress PDF Images + for (int i = 0; i < document.getPages().getCount(); i++) { + + PdfPageBase page = document.getPages().get(i); + PdfImageInfo[] images = page.getImagesInfo(); + if (images != null && images.length > 0) + for (int j = 0; j < images.length; j++) { + PdfImageInfo image = images[j]; + PdfBitmap bp = new PdfBitmap(image.getImage()); + //bp.setPngDirectToJpeg(true); + bp.setQuality(Integer.valueOf(imageCompressionLevel)); + + page.replaceImage(j, bp); + + } + } + + // Save the rearranged PDF to a ByteArrayOutputStream + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + document.saveToStream(outputStream); + + // Close the original document + document.close(); + + // Prepare the response headers + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_PDF); + headers.setContentDispositionFormData("attachment", "compressed.pdf"); + headers.setContentLength(outputStream.size()); + + // Return the response with the PDF data and headers + return new ResponseEntity<>(outputStream.toByteArray(), headers, HttpStatus.OK); + } + +} diff --git a/src/main/java/stirling/software/SPDF/controller/ConvertPDFController.java b/src/main/java/stirling/software/SPDF/controller/ConvertPDFController.java new file mode 100644 index 00000000..9ac68249 --- /dev/null +++ b/src/main/java/stirling/software/SPDF/controller/ConvertPDFController.java @@ -0,0 +1,45 @@ +package stirling.software.SPDF.controller; + +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +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 ConvertPDFController { + + private static final Logger logger = LoggerFactory.getLogger(ConvertPDFController.class); + + @GetMapping("/convert-pdf") + public String convertToPdfForm(Model model) { + model.addAttribute("currentPage", "convert-pdf"); + return "convert-pdf"; + } + + @PostMapping("/convert-to-pdf") + public ResponseEntity convertToPdf(@RequestParam("fileInput") MultipartFile file) throws IOException { + // Convert the file to PDF and get the resulting bytes + byte[] bytes = PdfUtils.convertToPdf(file.getInputStream()); + logger.info("File {} successfully converted to pdf", file.getOriginalFilename()); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_PDF); + String filename = "converted.pdf"; + headers.setContentDispositionFormData(filename, filename); + headers.setCacheControl("must-revalidate, post-check=0, pre-check=0"); + ResponseEntity response = new ResponseEntity<>(bytes, headers, HttpStatus.OK); + return response; + } +} diff --git a/src/main/java/stirling/software/SPDF/controller/FromPDFController.java b/src/main/java/stirling/software/SPDF/controller/FromPDFController.java index 17a28c27..00c33616 100644 --- a/src/main/java/stirling/software/SPDF/controller/FromPDFController.java +++ b/src/main/java/stirling/software/SPDF/controller/FromPDFController.java @@ -21,10 +21,6 @@ public class FromPDFController { private static final Logger logger = LoggerFactory.getLogger(FromPDFController.class); - @GetMapping("/convert-from-pdf") - public String convertFromPdfForm() { - return "convert-from-pdf"; - } @PostMapping("/convert-from-pdf") public ResponseEntity convertToImage(@RequestParam("fileInput") MultipartFile file, @@ -42,7 +38,7 @@ public class FromPDFController { private String getMediaType(String imageFormat) { if(imageFormat.equalsIgnoreCase("PNG")) return "image/png"; - else if(imageFormat.equalsIgnoreCase("JPEG") || imageFormat.equalsIgnoreCase("JPG") ) + else if(imageFormat.equalsIgnoreCase("JPEG") || imageFormat.equalsIgnoreCase("JPG")) return "image/jpeg"; else if(imageFormat.equalsIgnoreCase("GIF")) return "image/gif"; diff --git a/src/main/java/stirling/software/SPDF/controller/OverlayImageController.java b/src/main/java/stirling/software/SPDF/controller/OverlayImageController.java index d9b2b429..f2a28469 100644 --- a/src/main/java/stirling/software/SPDF/controller/OverlayImageController.java +++ b/src/main/java/stirling/software/SPDF/controller/OverlayImageController.java @@ -9,6 +9,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; 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; @@ -22,7 +23,8 @@ public class OverlayImageController { private static final Logger logger = LoggerFactory.getLogger(OverlayImageController.class); @GetMapping("/add-image") - public String overlayImage() { + public String overlayImage(Model model) { + model.addAttribute("currentPage", "add-image"); return "add-image"; } diff --git a/src/main/java/stirling/software/SPDF/controller/PdfController.java b/src/main/java/stirling/software/SPDF/controller/PdfController.java index caad2052..e66fb9a5 100644 --- a/src/main/java/stirling/software/SPDF/controller/PdfController.java +++ b/src/main/java/stirling/software/SPDF/controller/PdfController.java @@ -33,13 +33,13 @@ public class PdfController { @GetMapping("/merge-pdfs") public String hello(Model model) { - model.addAttribute("message", "Hello, World!"); + model.addAttribute("currentPage", "merge-pdfs"); return "merge-pdfs"; } @GetMapping("/home") public String home(Model model) { - model.addAttribute("message", "Hello, World!"); + model.addAttribute("currentPage", "home"); return "home"; } diff --git a/src/main/java/stirling/software/SPDF/controller/RearrangePagesPDFController.java b/src/main/java/stirling/software/SPDF/controller/RearrangePagesPDFController.java index 38906a4e..c07ee4e1 100644 --- a/src/main/java/stirling/software/SPDF/controller/RearrangePagesPDFController.java +++ b/src/main/java/stirling/software/SPDF/controller/RearrangePagesPDFController.java @@ -27,6 +27,7 @@ public class RearrangePagesPDFController { @GetMapping("/pdf-organizer") public String pageOrganizer(Model model) { + model.addAttribute("currentPage", "pdf-organizer"); return "pdf-organizer"; } diff --git a/src/main/java/stirling/software/SPDF/controller/RotationController.java b/src/main/java/stirling/software/SPDF/controller/RotationController.java new file mode 100644 index 00000000..233b2067 --- /dev/null +++ b/src/main/java/stirling/software/SPDF/controller/RotationController.java @@ -0,0 +1,74 @@ +package stirling.software.SPDF.controller; + +import java.io.ByteArrayOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Iterator; +import java.util.ListIterator; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageTree; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +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 RotationController { + + private static final Logger logger = LoggerFactory.getLogger(RotationController.class); + + @GetMapping("/rotate-pdf") + public String rotatePdfForm(Model model) { + model.addAttribute("currentPage", "rotate-pdf"); + return "rotate-pdf"; + } + + @PostMapping("/rotate-pdf") + public ResponseEntity rotatePDF(@RequestParam("fileInput") MultipartFile pdfFile, + @RequestParam("angle") String angle) throws IOException { + + // Load the PDF document + PDDocument document = PDDocument.load(pdfFile.getBytes()); + + // Get the list of pages in the document + PDPageTree pages = document.getPages(); + + // Rotate all pages by the specified angle + Iterator iterPage = pages.iterator(); + + while (iterPage.hasNext()) { + PDPage page = iterPage.next(); + page.setRotation(Integer.valueOf(angle)); + } + + // Save the rearranged PDF to a ByteArrayOutputStream + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + document.save(outputStream); + + // Close the document + document.close(); + + // Prepare the response headers + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_PDF); + headers.setContentDispositionFormData("attachment", "output.pdf"); + headers.setContentLength(outputStream.size()); + + // Return the response with the PDF data and headers + return new ResponseEntity<>(outputStream.toByteArray(), headers, HttpStatus.OK); + + } + +} diff --git a/src/main/java/stirling/software/SPDF/controller/SplitPDFController.java b/src/main/java/stirling/software/SPDF/controller/SplitPDFController.java index 8ed5aef8..c283e5b5 100644 --- a/src/main/java/stirling/software/SPDF/controller/SplitPDFController.java +++ b/src/main/java/stirling/software/SPDF/controller/SplitPDFController.java @@ -28,6 +28,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; 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; @@ -39,7 +40,8 @@ public class SplitPDFController { private static final Logger logger = LoggerFactory.getLogger(SplitPDFController.class); @GetMapping("/split-pdfs") - public String splitPdfForm() { + public String splitPdfForm(Model model) { + model.addAttribute("currentPage", "split-pdfs"); return "split-pdfs"; } diff --git a/src/main/resources/static/general.css b/src/main/resources/static/general.css index aa23b739..20e97c59 100644 --- a/src/main/resources/static/general.css +++ b/src/main/resources/static/general.css @@ -2,4 +2,4 @@ position: absolute; bottom: 0; width: 100%; -} \ No newline at end of file +} diff --git a/src/main/resources/templates/compress-pdf.html b/src/main/resources/templates/compress-pdf.html new file mode 100644 index 00000000..da519f2f --- /dev/null +++ b/src/main/resources/templates/compress-pdf.html @@ -0,0 +1,43 @@ + + + + + +S-PDF Add-Image + + + +
+
+
+
+
+
+

Compress PDF

+ + + +
+

Warning: This process can take up to a minute depending on file-size

+
+ +
+
+ +
+ + +
+ + +
+
+
+
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/convert-pdf.html b/src/main/resources/templates/convert-pdf.html new file mode 100644 index 00000000..798cdb2c --- /dev/null +++ b/src/main/resources/templates/convert-pdf.html @@ -0,0 +1,61 @@ + + + + +S-PDF ConvertToPDF + + + +
+
+
+
+
+
+

Image to PDF

+ +
+
+ +
+

+ + +
+ +
+
+
+

+
+
+
+

PDF to img

+
+
+ +
+
+ +
+ +
+ + +
+
+
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/home.html b/src/main/resources/templates/home.html index afc6da3e..04600e58 100644 --- a/src/main/resources/templates/home.html +++ b/src/main/resources/templates/home.html @@ -1,84 +1,108 @@ - - - - -S-PDF - - - -
- -
-
-

Stirling PDF

-

Your locally hosted one-stop-shop for all your - PDF needs. (Made 100% in ChatGPT in 1 day as a experiment)

-
-
- - -
-
-
-
-
-
Merge PDFs
-

Easily merge multiple PDFs into one.

- Go -
-
-
-
-
-
-
Split PDFs
-

Split your PDFs into multiple single-page - documents or at specific page numbers.

- Go -
-
-
-
-
-
-
Convert to PDF
-

Convert images to PDF.

- Go -
-
-
-
-
-
-
-
-
Convert from PDF
-

Convert PDF to Image.

- Go -
-
-
-
-
-
-
Add image to PDF
-

Adds image/watermark to a PDF

- Go -
-
-
-
-
-
-
PDF Organizer
-

Rearrange PDF pages into any order (or - remove)

- Go -
-
-
-
-
-
- + + + + + + S-PDF + + + +
+ +
+
+

Stirling PDF

+

Your locally hosted one-stop-shop for all your + PDF needs. (Made 100% in ChatGPT in 1 day as a experiment)

+
+
+ + + + +
+
+
+
+
+
Merge PDFs
+

Easily merge multiple PDFs into one.

+ Go +
+
+
+
+
+
+
Split PDFs
+

Split PDFs into multiple documents

+ Go +
+
+
+
+
+
+
Add image to PDF
+

Adds image/watermark to a PDF

+ Go +
+
+
+
+
+
+
+
+
+
Convert to/from PDF
+

Convert images to/from PDF.

+ Go +
+
+
+ +
+
+
+
PDF Organizer
+

Remove/Rearrange pages in any order

+ Go +
+
+
+ +
+
+
+
Rotate PDFs
+

Easily rotate your PDFs.

+ Go +
+
+
+ +
+
+
+ + + + + +
+
+
+
Compress PDFs
+

Compress PDFs to reduce their file size.

+ Go +
+
+
+ +
+
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/navbar.html b/src/main/resources/templates/navbar.html index ea5df482..0b80f9c9 100644 --- a/src/main/resources/templates/navbar.html +++ b/src/main/resources/templates/navbar.html @@ -12,29 +12,31 @@ - + th:href="@{/convert-pdf}" + th:classappend="${currentPage}=='convert-pdf' ? 'active' : ''">Convert + to/from PDF - + + + Dark Mode diff --git a/src/main/resources/templates/rotate-pdf.html b/src/main/resources/templates/rotate-pdf.html new file mode 100644 index 00000000..ceb23f74 --- /dev/null +++ b/src/main/resources/templates/rotate-pdf.html @@ -0,0 +1,47 @@ + + + + + +S-PDF Add-Image + + + +
+
+
+
+
+
+

Rotate PDF

+ + + +
+
+ +
+ +
+ +
+ + +
+
+
+
+ + + \ No newline at end of file