From f79ec46f831b9b7cbedffe4c2e7b53ae7d38efa2 Mon Sep 17 00:00:00 2001 From: Trevor Cox Date: Mon, 26 Jan 2015 14:12:22 -0500 Subject: [PATCH 1/4] Add -t option to stamp one or more text strings as well as image. Omit datestamp from output filename. Print stacktrace on exception. --- .gitignore | 2 +- build.xml | 2 +- src/com/appazur/pdfstamp/TextStampTuple.java | 54 +++++++++++++++++ src/org/crossref/pdfstamp/Main.java | 64 +++++++++++++++++++- 4 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 src/com/appazur/pdfstamp/TextStampTuple.java diff --git a/.gitignore b/.gitignore index 013c995..9aafd68 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ bin classes target -pdfstamp-*.jar +pdfstamp*.jar diff --git a/build.xml b/build.xml index 8c06b9e..2c3aa1c 100644 --- a/build.xml +++ b/build.xml @@ -17,7 +17,7 @@ - + diff --git a/src/com/appazur/pdfstamp/TextStampTuple.java b/src/com/appazur/pdfstamp/TextStampTuple.java new file mode 100644 index 0000000..eb1fb4e --- /dev/null +++ b/src/com/appazur/pdfstamp/TextStampTuple.java @@ -0,0 +1,54 @@ +/** +The MIT License (MIT) + +Copyright (c) 2015 Appazur Solutions Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +package com.appazur.pdfstamp; + +import org.kohsuke.args4j.CmdLineException; + +public class TextStampTuple { + public float x; + public float y; + public String text; + + public TextStampTuple(String paramValue) throws CmdLineException { + final String[] components = paramValue.split(","); + + if (components.length != 3) { + /* Each TextStampTuple should have x,y,text . */ + throw new CmdLineException("Must specify X,Y,TEXT for text stamp."); + } + + try { + this.x = Float.parseFloat(components[0]); + this.y = Float.parseFloat(components[1]); + + // Since spaces are used to separate arguments to -t, + // need to provide an alternate way to provide spaces. + this.text = components[2].replace('_',' '); + + } catch (NumberFormatException e) { + throw new CmdLineException("X and Y must be specified as rational numbers."); + } + } +} diff --git a/src/org/crossref/pdfstamp/Main.java b/src/org/crossref/pdfstamp/Main.java index 3bdab77..75542e9 100644 --- a/src/org/crossref/pdfstamp/Main.java +++ b/src/org/crossref/pdfstamp/Main.java @@ -1,3 +1,11 @@ +/** + +Changes to the original file, https://github.com/CrossRef/pdfstamp/blob/master/src/org/crossref/pdfstamp/Main.java +are released under the the MIT License (MIT) +and are copyright (c) 2015 Appazur Solutions Inc. + +*/ + package org.crossref.pdfstamp; import com.itextpdf.text.DocumentException; @@ -16,6 +24,7 @@ import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.Option; +import org.kohsuke.args4j.spi.StringArrayOptionHandler; import com.itextpdf.text.BadElementException; import com.itextpdf.text.pdf.PdfAction; @@ -23,6 +32,17 @@ import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; +import com.itextpdf.text.pdf.ColumnText; +import com.itextpdf.text.Phrase; +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.Font; +import com.itextpdf.text.Font.FontFamily; +import com.itextpdf.text.FontFactory; + +import com.appazur.pdfstamp.TextStampTuple; + + + // -u "http://blah.com" -i somefile.jpeg -l 1,44.5,22.3,3,22.2,22.2 some/dir // or some.file @@ -65,7 +85,14 @@ public class Main { @Option(name="-d", usage="Optional. Target DPI. Defaults to 300.", required=false, multiValued=false) private int targetDpi = 300; - + + // Note: separate multiple values by a space, e.g. -t 1,1,Hello 2,2,World. + // To use the value of the -u argument, use "=URL" as the value for TEXT. + @Option(name="-t", usage="Optional. Text to stamp. (Multiple values allowed.)", + handler = StringArrayOptionHandler.class, + required=true, multiValued=false, metaVar="X,Y,TEXT ...") + String[] textStampList; + @Argument private List paths = new ArrayList(); @@ -132,7 +159,7 @@ private static PdfStamper openStamper(File f, PdfReader r) * at the same location. The action area covers the the image. */ private void stampPdf(PdfStamper s, Image i, float x, float y, int page) - throws DocumentException { + throws DocumentException, CmdLineException { /* Assume 72 DPI images if not specified. */ final float scaleFactorX = (i.getDpiX() == 0 ? 72f : i.getDpiX()) / targetDpi; final float scaleFactorY = (i.getDpiY() == 0 ? 72f : i.getDpiY()) / targetDpi; @@ -152,6 +179,31 @@ private void stampPdf(PdfStamper s, Image i, float x, float y, int page) x + scaledImgWidth, y); } + + for(String tss: this.textStampList) { + if(verbose) { + System.err.println(tss); + } + TextStampTuple tst = new TextStampTuple(tss); + ColumnText ct = new ColumnText( content ); + // These are the coordinates where you want to add text. + // If the text does not fit inside it will be cropped. + ct.setSimpleColumn(tst.x, tst.y, tst.x+300, tst.y+50); + Phrase p; + // special case: if text is "=URL", use url as text. + if(tst.text.equals("=URL")) { + p = new Phrase(url); + } + else { + p = new Phrase(tst.text, + FontFactory.getFont("Trebuchet MS", 16, + Font.BOLD, BaseColor.WHITE)); + } + + ct.setText(p); + ct.go(); + } + content.restoreState(); } } @@ -196,6 +248,9 @@ private void addStampsToFile(File in, File out) { } catch (Exception e) { System.err.println("Failed on " + in.getPath() + " because of:"); System.err.println(e); + if(verbose) { + e.printStackTrace(); + } } finally { try { if (s != null) { @@ -277,6 +332,11 @@ private void doMain(String... args) { } catch (CmdLineException e) { System.err.println(e.getMessage()); parser.printUsage(System.err); + } catch (Exception e) { + System.err.println(e.getMessage()); + if(verbose) { + e.printStackTrace(); + } } } From a54664193052d9396d0c0cc4b9d9e309dcadea2e Mon Sep 17 00:00:00 2001 From: Trevor Cox Date: Mon, 26 Jan 2015 14:21:26 -0500 Subject: [PATCH 2/4] Create README.md --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..8d1aeee --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# pdfstamp +Stamp a PDF with an image and clickable URL, AND text strings. + +Code assumes 72dpi if it can't find out from file, then scales to 300dpi unless otherwise specified. + +This is a work-in-progress. Needs configuration for text font (currently white). + +Stamp a PDF with an image and clickable URL, AND text strings. + +Code assumes 72dpi if it can't find out from file, then scales to 300dpi unless otherwise specified. + +This is a work-in-progress. Needs configuration for text font (currently white). + +``` + java -jar ./pdfstamp.jar + Usage: pdfstamp [options] | + -d N : Optional. Target DPI. Defaults to 300. + -e EXT : Optional. Extension appended to the PDF filename. + -i FILE : Required. Image file containing image of the stamp. + -l X,Y : Required. Location on page to apply stamp. + -o FILE : Optional. Output directory. + -p P1,P2... : Optional. Page numbers to stamp. -1 is the last page. + -r : Optional. Descend recursively into directories. + -t X,Y,TEXT ... : Optional. Text to stamp. (Multiple values allowed.) + -u URL : Optional. Target URL of the stamp. + -v : Optional. Verbose output. +``` + +New -t argument: + +Separate multiple values by a space, e.g. -t 1,1,Hello 2,2,World. +To use the value of the -u argument, use "=URL" as the value for TEXT. From 02d18adaed7c9b5ab9d3b5a60c4749cee59ae6b1 Mon Sep 17 00:00:00 2001 From: Trevor Cox Date: Mon, 26 Jan 2015 14:23:23 -0500 Subject: [PATCH 3/4] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 8d1aeee..dff940f 100644 --- a/README.md +++ b/README.md @@ -30,3 +30,7 @@ New -t argument: Separate multiple values by a space, e.g. -t 1,1,Hello 2,2,World. To use the value of the -u argument, use "=URL" as the value for TEXT. + +Original project: https://github.com/CrossRef/pdfstamp + +Text stamping added by http://www.appazur.com From 7f3384e4fb6acab21a007586e1314285723f32b8 Mon Sep 17 00:00:00 2001 From: Trevor Cox Date: Mon, 26 Jan 2015 19:55:46 -0500 Subject: [PATCH 4/4] Formatting changes. --- src/org/crossref/pdfstamp/Main.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/org/crossref/pdfstamp/Main.java b/src/org/crossref/pdfstamp/Main.java index 75542e9..faf456a 100644 --- a/src/org/crossref/pdfstamp/Main.java +++ b/src/org/crossref/pdfstamp/Main.java @@ -38,6 +38,7 @@ and are copyright (c) 2015 Appazur Solutions Inc. import com.itextpdf.text.Font; import com.itextpdf.text.Font.FontFamily; import com.itextpdf.text.FontFactory; +import com.itextpdf.text.Element; import com.appazur.pdfstamp.TextStampTuple; @@ -186,18 +187,24 @@ private void stampPdf(PdfStamper s, Image i, float x, float y, int page) } TextStampTuple tst = new TextStampTuple(tss); ColumnText ct = new ColumnText( content ); + // These are the coordinates where you want to add text. // If the text does not fit inside it will be cropped. ct.setSimpleColumn(tst.x, tst.y, tst.x+300, tst.y+50); Phrase p; // special case: if text is "=URL", use url as text. if(tst.text.equals("=URL")) { - p = new Phrase(url); + tst.text = url; + } + + if(tst.text.startsWith("http")) { + p = new Phrase(tst.text); } else { p = new Phrase(tst.text, FontFactory.getFont("Trebuchet MS", 16, Font.BOLD, BaseColor.WHITE)); + ct.setAlignment(Element.ALIGN_RIGHT); } ct.setText(p);