overlay fix for sequential

This commit is contained in:
Anthony Stirling 2023-12-29 22:53:46 +00:00
parent 80a59205fa
commit e6622dfdc4

View file

@ -3,8 +3,9 @@ import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.ArrayList;
import org.apache.pdfbox.multipdf.Overlay; import org.apache.pdfbox.multipdf.Overlay;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -33,6 +34,8 @@ public class PdfOverlayController {
MultipartFile[] overlayFiles = request.getOverlayFiles(); MultipartFile[] overlayFiles = request.getOverlayFiles();
File[] overlayPdfFiles = new File[overlayFiles.length]; File[] overlayPdfFiles = new File[overlayFiles.length];
List<File> tempFiles = new ArrayList<>(); // List to keep track of temporary files
try { try {
for (int i = 0; i < overlayFiles.length; i++) { for (int i = 0; i < overlayFiles.length; i++) {
overlayPdfFiles[i] = GeneralUtils.multipartToFile(overlayFiles[i]); overlayPdfFiles[i] = GeneralUtils.multipartToFile(overlayFiles[i]);
@ -43,7 +46,7 @@ public class PdfOverlayController {
try (PDDocument basePdf = PDDocument.load(baseFile.getInputStream()); try (PDDocument basePdf = PDDocument.load(baseFile.getInputStream());
Overlay overlay = new Overlay()) { Overlay overlay = new Overlay()) {
Map<Integer, String> overlayGuide = prepareOverlayGuide(basePdf.getNumberOfPages(), overlayPdfFiles, mode, counts); Map<Integer, String> overlayGuide = prepareOverlayGuide(basePdf.getNumberOfPages(), overlayPdfFiles, mode, counts, tempFiles);
overlay.setInputPDF(basePdf); overlay.setInputPDF(basePdf);
if (overlayPos == 0) { if (overlayPos == 0) {
@ -61,16 +64,23 @@ public class PdfOverlayController {
} }
} finally { } finally {
for (File overlayPdfFile : overlayPdfFiles) { for (File overlayPdfFile : overlayPdfFiles) {
if (overlayPdfFile != null) overlayPdfFile.delete(); if (overlayPdfFile != null) {
overlayPdfFile.delete();
}
}
for (File tempFile : tempFiles) { // Delete temporary files
if (tempFile != null) {
tempFile.delete();
}
} }
} }
} }
private Map<Integer, String> prepareOverlayGuide(int basePageCount, File[] overlayFiles, String mode, int[] counts) throws IOException { private Map<Integer, String> prepareOverlayGuide(int basePageCount, File[] overlayFiles, String mode, int[] counts, List<File> tempFiles) throws IOException {
Map<Integer, String> overlayGuide = new HashMap<>(); Map<Integer, String> overlayGuide = new HashMap<>();
switch (mode) { switch (mode) {
case "SequentialOverlay": case "SequentialOverlay":
sequentialOverlay(overlayGuide, overlayFiles, basePageCount); sequentialOverlay(overlayGuide, overlayFiles, basePageCount, tempFiles);
break; break;
case "InterleavedOverlay": case "InterleavedOverlay":
interleavedOverlay(overlayGuide, overlayFiles, basePageCount); interleavedOverlay(overlayGuide, overlayFiles, basePageCount);
@ -84,27 +94,57 @@ public class PdfOverlayController {
return overlayGuide; return overlayGuide;
} }
private void sequentialOverlay(Map<Integer, String> overlayGuide, File[] overlayFiles, int basePageCount) throws IOException { private void sequentialOverlay(Map<Integer, String> overlayGuide, File[] overlayFiles, int basePageCount, List<File> tempFiles) throws IOException {
if (overlayFiles.length != 1 || basePageCount != PDDocument.load(overlayFiles[0]).getNumberOfPages()) { int overlayFileIndex = 0;
throw new IllegalArgumentException("Overlay file count and base page count must match for sequential overlay."); int pageCountInCurrentOverlay = 0;
for (int basePageIndex = 1; basePageIndex <= basePageCount; basePageIndex++) {
if (pageCountInCurrentOverlay == 0 || pageCountInCurrentOverlay >= getNumberOfPages(overlayFiles[overlayFileIndex])) {
pageCountInCurrentOverlay = 0;
overlayFileIndex = (overlayFileIndex + 1) % overlayFiles.length;
} }
File overlayFile = overlayFiles[0]; try (PDDocument overlayPdf = PDDocument.load(overlayFiles[overlayFileIndex])) {
try (PDDocument overlayPdf = PDDocument.load(overlayFile)) { PDDocument singlePageDocument = new PDDocument();
for (int i = 1; i <= overlayPdf.getNumberOfPages(); i++) { singlePageDocument.addPage(overlayPdf.getPage(pageCountInCurrentOverlay));
if (i > basePageCount) break; File tempFile = File.createTempFile("overlay-page-", ".pdf");
overlayGuide.put(i, overlayFile.getAbsolutePath()); singlePageDocument.save(tempFile);
singlePageDocument.close();
overlayGuide.put(basePageIndex, tempFile.getAbsolutePath());
tempFiles.add(tempFile); // Keep track of the temporary file for cleanup
}
pageCountInCurrentOverlay++;
} }
} }
private int getNumberOfPages(File file) throws IOException {
try (PDDocument doc = PDDocument.load(file)) {
return doc.getNumberOfPages();
} }
}
private void interleavedOverlay(Map<Integer, String> overlayGuide, File[] overlayFiles, int basePageCount) throws IOException { private void interleavedOverlay(Map<Integer, String> overlayGuide, File[] overlayFiles, int basePageCount) throws IOException {
for (int i = 0; i < basePageCount; i++) { for (int basePageIndex = 1; basePageIndex <= basePageCount; basePageIndex++) {
File overlayFile = overlayFiles[i % overlayFiles.length]; File overlayFile = overlayFiles[(basePageIndex - 1) % overlayFiles.length];
overlayGuide.put(i + 1, overlayFile.getAbsolutePath());
// Load the overlay document to check its page count
try (PDDocument overlayPdf = PDDocument.load(overlayFile)) {
int overlayPageCount = overlayPdf.getNumberOfPages();
if ((basePageIndex - 1) % overlayPageCount < overlayPageCount) {
overlayGuide.put(basePageIndex, overlayFile.getAbsolutePath());
} }
} }
}
}
private void fixedRepeatOverlay(Map<Integer, String> overlayGuide, File[] overlayFiles, int[] counts, int basePageCount) throws IOException { private void fixedRepeatOverlay(Map<Integer, String> overlayGuide, File[] overlayFiles, int[] counts, int basePageCount) throws IOException {
if (overlayFiles.length != counts.length) { if (overlayFiles.length != counts.length) {
@ -114,12 +154,20 @@ public class PdfOverlayController {
for (int i = 0; i < overlayFiles.length; i++) { for (int i = 0; i < overlayFiles.length; i++) {
File overlayFile = overlayFiles[i]; File overlayFile = overlayFiles[i];
int repeatCount = counts[i]; int repeatCount = counts[i];
// Load the overlay document to check its page count
try (PDDocument overlayPdf = PDDocument.load(overlayFile)) {
int overlayPageCount = overlayPdf.getNumberOfPages();
for (int j = 0; j < repeatCount; j++) { for (int j = 0; j < repeatCount; j++) {
for (int page = 0; page < overlayPageCount; page++) {
if (currentPage > basePageCount) break; if (currentPage > basePageCount) break;
overlayGuide.put(currentPage++, overlayFile.getAbsolutePath()); overlayGuide.put(currentPage++, overlayFile.getAbsolutePath());
} }
} }
} }
} }
}
}
// Additional classes like OverlayPdfsRequest, WebResponseUtils, etc. are assumed to be defined elsewhere. // Additional classes like OverlayPdfsRequest, WebResponseUtils, etc. are assumed to be defined elsewhere.