From 40e4fbabe6b7e96f89c4b26cefe2793e3e546684 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Fri, 3 Mar 2023 00:00:22 +0000 Subject: [PATCH] init --- .../controller/ExtractImagesController.java | 158 ++++++++++++++++++ .../resources/templates/extract-images.html | 112 +++++++++++++ .../resources/templates/fragments/navbar.html | 6 + 3 files changed, 276 insertions(+) create mode 100644 src/main/java/stirling/software/SPDF/controller/ExtractImagesController.java create mode 100644 src/main/resources/templates/extract-images.html diff --git a/src/main/java/stirling/software/SPDF/controller/ExtractImagesController.java b/src/main/java/stirling/software/SPDF/controller/ExtractImagesController.java new file mode 100644 index 000000000..8a2e021e4 --- /dev/null +++ b/src/main/java/stirling/software/SPDF/controller/ExtractImagesController.java @@ -0,0 +1,158 @@ +package stirling.software.SPDF.controller; + +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.awt.image.RenderedImage; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; +import java.util.zip.Deflater; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import javax.imageio.ImageIO; + +import org.apache.pdfbox.contentstream.operator.Operator; +import org.apache.pdfbox.cos.COSDocument; +import org.apache.pdfbox.cos.COSName; +import org.apache.pdfbox.pdfparser.PDFParser; +import org.apache.pdfbox.pdfparser.PDFStreamParser; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageTree; +import org.apache.pdfbox.pdmodel.PDResources; +import org.apache.pdfbox.pdmodel.common.PDStream; +import org.apache.pdfbox.pdmodel.graphics.PDXObject; +import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; +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; +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.itextpdf.text.pdf.PdfDocument; +import com.itextpdf.text.pdf.PdfPage; +import com.itextpdf.text.pdf.PdfReader; + +@Controller +public class ExtractImagesController { + + private static final Logger logger = LoggerFactory.getLogger(ExtractImagesController.class); + + @GetMapping("/extract-images") + public String extractImagesForm(Model model) { + model.addAttribute("currentPage", "extract-images"); + return "extract-images"; + } + + @PostMapping("/extract-images") + public ResponseEntity extractImages(@RequestParam("fileInput") MultipartFile file, @RequestParam("format") String format) throws IOException { + + System.out.println(System.currentTimeMillis() + "file=" + file.getName() + ", format=" + format); + PDDocument document = PDDocument.load(file.getBytes()); + + // Create ByteArrayOutputStream to write zip file to byte array + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + // Create ZipOutputStream to create zip file + ZipOutputStream zos = new ZipOutputStream(baos); + + // Set compression level + zos.setLevel(Deflater.BEST_COMPRESSION); + + int imageIndex = 1; + + int pageNum = 1; + // Iterate over each page + for (PDPage page : document.getPages()) { + ++pageNum; + // Extract images from page + for (COSName name : page.getResources().getXObjectNames()) { + if (page.getResources().isImageXObject(name)) { + PDImageXObject image = (PDImageXObject) page.getResources().getXObject(name); + + // Convert image to desired format + RenderedImage renderedImage = image.getImage(); + BufferedImage bufferedImage = null; + if (format.equalsIgnoreCase("png")) { + bufferedImage = new BufferedImage(renderedImage.getWidth(), renderedImage.getHeight(), + BufferedImage.TYPE_INT_ARGB); + } else if (format.equalsIgnoreCase("jpeg") || format.equalsIgnoreCase("jpg")) { + bufferedImage = new BufferedImage(renderedImage.getWidth(), renderedImage.getHeight(), + BufferedImage.TYPE_INT_RGB); + } else if (format.equalsIgnoreCase("gif")) { + bufferedImage = new BufferedImage(renderedImage.getWidth(), renderedImage.getHeight(), + BufferedImage.TYPE_BYTE_INDEXED); + } + + // Write image to zip file + String imageName = "Image " + imageIndex + " (Page " + pageNum + ")." + format; + ZipEntry zipEntry = new ZipEntry(imageName); + zos.putNextEntry(zipEntry); + + Graphics2D g = bufferedImage.createGraphics(); + g.drawImage((Image) renderedImage, 0, 0, null); + g.dispose(); + // Write image bytes to zip file + ByteArrayOutputStream imageBaos = new ByteArrayOutputStream(); + ImageIO.write(bufferedImage, format, imageBaos); + zos.write(imageBaos.toByteArray()); + + + zos.closeEntry(); + imageIndex++; + } + } + } + + // Close ZipOutputStream and PDDocument + zos.close(); + document.close(); + + // Create ByteArrayResource from byte array + byte[] zipContents = baos.toByteArray(); + ByteArrayResource resource = new ByteArrayResource(zipContents); + + // Set content disposition header to indicate that the response should be downloaded as a file + HttpHeaders headers = new HttpHeaders(); + headers.setContentLength(zipContents.length); + headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + file.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_extracted-images.zip"); + + // Return ResponseEntity with ByteArrayResource and headers + return ResponseEntity + .status(HttpStatus.OK) + .headers(headers) + + .header("Cache-Control", "no-cache") + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .body(resource); + } + + +} diff --git a/src/main/resources/templates/extract-images.html b/src/main/resources/templates/extract-images.html new file mode 100644 index 000000000..ea63cd7a3 --- /dev/null +++ b/src/main/resources/templates/extract-images.html @@ -0,0 +1,112 @@ + + + + + + + +
+
+
+

+
+
+
+

+ +
+
+
+ + +
+ +
+ + + + +
+
+
+
+
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/fragments/navbar.html b/src/main/resources/templates/fragments/navbar.html index 2f760d309..5ae58ebf3 100644 --- a/src/main/resources/templates/fragments/navbar.html +++ b/src/main/resources/templates/fragments/navbar.html @@ -67,6 +67,7 @@ + @@ -86,6 +87,11 @@ +