page adjusts for stamp

This commit is contained in:
Anthony Stirling 2024-02-10 14:52:27 +00:00
parent e1c3561997
commit 0fabfea56d
6 changed files with 48 additions and 31 deletions

View file

@ -50,7 +50,7 @@ public class SplitPDFController {
PDDocument document = Loader.loadPDF(file.getBytes()); PDDocument document = Loader.loadPDF(file.getBytes());
List<Integer> pageNumbers = request.getPageNumbersList(document); List<Integer> pageNumbers = request.getPageNumbersList(document, true);
if (!pageNumbers.contains(document.getNumberOfPages() - 1)) if (!pageNumbers.contains(document.getNumberOfPages() - 1))
pageNumbers.add(document.getNumberOfPages() - 1); pageNumbers.add(document.getNumberOfPages() - 1);
logger.info( logger.info(

View file

@ -49,13 +49,13 @@ public class StampController {
@Operation( @Operation(
summary = "Add stamp to a PDF file", summary = "Add stamp to a PDF file",
description = description =
"This endpoint adds a stamp to a given PDF file. Users can specify the watermark type (text or image), rotation, opacity, width spacer, and height spacer. Input:PDF Output:PDF Type:SISO") "This endpoint adds a stamp to a given PDF file. Users can specify the stamp type (text or image), rotation, opacity, width spacer, and height spacer. Input:PDF Output:PDF Type:SISO")
public ResponseEntity<byte[]> addStamp(@ModelAttribute AddStampRequest request) public ResponseEntity<byte[]> addStamp(@ModelAttribute AddStampRequest request)
throws IOException, Exception { throws IOException, Exception {
MultipartFile pdfFile = request.getFileInput(); MultipartFile pdfFile = request.getFileInput();
String watermarkType = request.getStampType(); String stampType = request.getStampType();
String watermarkText = request.getStampText(); String stampText = request.getStampText();
MultipartFile watermarkImage = request.getStampImage(); MultipartFile stampImage = request.getStampImage();
String alphabet = request.getAlphabet(); String alphabet = request.getAlphabet();
float fontSize = request.getFontSize(); float fontSize = request.getFontSize();
float rotation = request.getRotation(); float rotation = request.getRotation();
@ -88,7 +88,9 @@ public class StampController {
// Load the input PDF // Load the input PDF
PDDocument document = Loader.loadPDF(pdfFile.getBytes()); PDDocument document = Loader.loadPDF(pdfFile.getBytes());
List<Integer> pageNumbers = request.getPageNumbersList();
List<Integer> pageNumbers = request.getPageNumbersList(document, false);
for (int pageIndex : pageNumbers) { for (int pageIndex : pageNumbers) {
int zeroBasedIndex = pageIndex - 1; int zeroBasedIndex = pageIndex - 1;
@ -105,10 +107,10 @@ public class StampController {
graphicsState.setNonStrokingAlphaConstant(opacity); graphicsState.setNonStrokingAlphaConstant(opacity);
contentStream.setGraphicsStateParameters(graphicsState); contentStream.setGraphicsStateParameters(graphicsState);
if ("text".equalsIgnoreCase(watermarkType)) { if ("text".equalsIgnoreCase(stampType)) {
addTextStamp( addTextStamp(
contentStream, contentStream,
watermarkText, stampText,
document, document,
page, page,
rotation, rotation,
@ -119,10 +121,10 @@ public class StampController {
overrideY, overrideY,
margin, margin,
customColor); customColor);
} else if ("image".equalsIgnoreCase(watermarkType)) { } else if ("image".equalsIgnoreCase(stampType)) {
addImageStamp( addImageStamp(
contentStream, contentStream,
watermarkImage, stampImage,
document, document,
page, page,
rotation, rotation,
@ -140,12 +142,12 @@ public class StampController {
document, document,
Filenames.toSimpleFileName(pdfFile.getOriginalFilename()) Filenames.toSimpleFileName(pdfFile.getOriginalFilename())
.replaceFirst("[.][^.]+$", "") .replaceFirst("[.][^.]+$", "")
+ "_watermarked.pdf"); + "_stamped.pdf");
} }
private void addTextStamp( private void addTextStamp(
PDPageContentStream contentStream, PDPageContentStream contentStream,
String watermarkText, String stampText,
PDDocument document, PDDocument document,
PDPage page, PDPage page,
float rotation, float rotation,
@ -214,9 +216,7 @@ public class StampController {
x = overrideX; x = overrideX;
y = overrideY; y = overrideY;
} else { } else {
x = x = calculatePositionX(pageSize, position, fontSize, font, fontSize, stampText, margin);
calculatePositionX(
pageSize, position, fontSize, font, fontSize, watermarkText, margin);
y = y =
calculatePositionY( calculatePositionY(
pageSize, position, calculateTextCapHeight(font, fontSize), margin); pageSize, position, calculateTextCapHeight(font, fontSize), margin);
@ -224,13 +224,13 @@ public class StampController {
contentStream.beginText(); contentStream.beginText();
contentStream.setTextMatrix(Matrix.getRotateInstance(Math.toRadians(rotation), x, y)); contentStream.setTextMatrix(Matrix.getRotateInstance(Math.toRadians(rotation), x, y));
contentStream.showText(watermarkText); contentStream.showText(stampText);
contentStream.endText(); contentStream.endText();
} }
private void addImageStamp( private void addImageStamp(
PDPageContentStream contentStream, PDPageContentStream contentStream,
MultipartFile watermarkImage, MultipartFile stampImage,
PDDocument document, PDDocument document,
PDPage page, PDPage page,
float rotation, float rotation,
@ -241,8 +241,8 @@ public class StampController {
float margin) float margin)
throws IOException { throws IOException {
// Load the watermark image // Load the stamp image
BufferedImage image = ImageIO.read(watermarkImage.getInputStream()); BufferedImage image = ImageIO.read(stampImage.getInputStream());
// Compute width based on original aspect ratio // Compute width based on original aspect ratio
float aspectRatio = (float) image.getWidth() / (float) image.getHeight(); float aspectRatio = (float) image.getWidth() / (float) image.getHeight();
@ -319,4 +319,4 @@ public class StampController {
private float calculateTextCapHeight(PDFont font, float fontSize) { private float calculateTextCapHeight(PDFont font, float fontSize) {
return font.getFontDescriptor().getCapHeight() / 1000 * fontSize; return font.getFontDescriptor().getCapHeight() / 1000 * fontSize;
} }
} }

View file

@ -24,8 +24,9 @@ public class PDFWithPageNums extends PDFFile {
"The pages to select, Supports ranges (e.g., '1,3,5-9'), or 'all' or functions in the format 'an+b' where 'a' is the multiplier of the page number 'n', and 'b' is a constant (e.g., '2n+1', '3n', '6n-5')\"") "The pages to select, Supports ranges (e.g., '1,3,5-9'), or 'all' or functions in the format 'an+b' where 'a' is the multiplier of the page number 'n', and 'b' is a constant (e.g., '2n+1', '3n', '6n-5')\"")
private String pageNumbers; private String pageNumbers;
@Hidden @Hidden
public List<Integer> getPageNumbersList() { public List<Integer> getPageNumbersList(boolean zeroCount) {
int pageCount = 0; int pageCount = 0;
try { try {
pageCount = Loader.loadPDF(getFileInput().getBytes()).getNumberOfPages(); pageCount = Loader.loadPDF(getFileInput().getBytes()).getNumberOfPages();
@ -33,13 +34,13 @@ public class PDFWithPageNums extends PDFFile {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
return GeneralUtils.parsePageString(pageNumbers, pageCount); return GeneralUtils.parsePageString(pageNumbers, pageCount, zeroCount);
} }
@Hidden @Hidden
public List<Integer> getPageNumbersList(PDDocument doc) { public List<Integer> getPageNumbersList(PDDocument doc,boolean zeroCount ) {
int pageCount = 0; int pageCount = 0;
pageCount = doc.getNumberOfPages(); pageCount = doc.getNumberOfPages();
return GeneralUtils.parsePageString(pageNumbers, pageCount); return GeneralUtils.parsePageString(pageNumbers, pageCount, zeroCount);
} }
} }

View file

@ -116,6 +116,9 @@ public class GeneralUtils {
} }
public static List<Integer> parsePageString(String pageOrder, int totalPages) { public static List<Integer> parsePageString(String pageOrder, int totalPages) {
return parsePageString(pageOrder, totalPages , false );
}
public static List<Integer> parsePageString(String pageOrder, int totalPages, boolean isOneBased) {
if (pageOrder == null || pageOrder.isEmpty()) { if (pageOrder == null || pageOrder.isEmpty()) {
return Collections.singletonList(1); return Collections.singletonList(1);
} }
@ -123,17 +126,23 @@ public class GeneralUtils {
// Convert the single number string to an integer and return it in a list // Convert the single number string to an integer and return it in a list
return Collections.singletonList(Integer.parseInt(pageOrder)); return Collections.singletonList(Integer.parseInt(pageOrder));
} }
return parsePageList(pageOrder.split(","), totalPages); return parsePageList(pageOrder.split(","), totalPages, isOneBased);
} }
public static List<Integer> parsePageList(String[] pageOrderArr, int totalPages) { public static List<Integer> parsePageList(String[] pageOrderArr, int totalPages) {
return parsePageList(pageOrderArr, totalPages, false);
}
public static List<Integer> parsePageList(String[] pageOrderArr, int totalPages, boolean isOneBased) {
List<Integer> newPageOrder = new ArrayList<>(); List<Integer> newPageOrder = new ArrayList<>();
int adjustmentFactor = isOneBased ? 1 : 0;
// loop through the page order array // loop through the page order array
for (String element : pageOrderArr) { for (String element : pageOrderArr) {
if ("all".equalsIgnoreCase(element)) { if ("all".equalsIgnoreCase(element)) {
for (int i = 0; i < totalPages; i++) { for (int i = 0; i < totalPages; i++) {
newPageOrder.add(i); newPageOrder.add(i+ adjustmentFactor);
} }
// As all pages are already added, no need to check further // As all pages are already added, no need to check further
break; break;
@ -164,7 +173,7 @@ public class GeneralUtils {
pageNum += constantExists ? constant : 0; pageNum += constantExists ? constant : 0;
if (pageNum <= totalPages && pageNum > 0) { if (pageNum <= totalPages && pageNum > 0) {
newPageOrder.add(pageNum - 1); newPageOrder.add(pageNum - adjustmentFactor);
} }
} }
} else if (element.contains("-")) { } else if (element.contains("-")) {
@ -179,11 +188,11 @@ public class GeneralUtils {
// loop through the range of pages // loop through the range of pages
for (int j = start; j <= end; j++) { for (int j = start; j <= end; j++) {
// print the current index // print the current index
newPageOrder.add(j - 1); newPageOrder.add(j - adjustmentFactor);
} }
} else { } else {
// if the element is a single page // if the element is a single page
newPageOrder.add(Integer.parseInt(element) - 1); newPageOrder.add(Integer.parseInt(element) - adjustmentFactor);
} }
} }

View file

@ -11,6 +11,7 @@ imgPrompt=Select Image(s)
genericSubmit=Submit genericSubmit=Submit
processTimeWarning=Warning: This process can take up to a minute depending on file-size processTimeWarning=Warning: This process can take up to a minute depending on file-size
pageOrderPrompt=Custom Page Order (Enter a comma-separated list of page numbers or Functions like 2n+1) : pageOrderPrompt=Custom Page Order (Enter a comma-separated list of page numbers or Functions like 2n+1) :
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
goToPage=Go goToPage=Go
true=True true=True
false=False false=False

View file

@ -22,6 +22,12 @@
<div <div
th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div> th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<br> <br>
<div class="mb-3">
<label for="pageOrder" th:text="#{pageSelectionPrompt}"></label>
<input type="text" class="form-control" id="pageOrder" name="pageNumbers" value="1" placeholder="(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)" required>
</div>
<div class="mb-3"> <div class="mb-3">
<label for="customMargin" class="form-label" th:text="#{AddStampRequest.customMargin}">Custom Margin</label> <label for="customMargin" class="form-label" th:text="#{AddStampRequest.customMargin}">Custom Margin</label>
<select class="form-select" id="customMargin" name="customMargin"> <select class="form-select" id="customMargin" name="customMargin">