1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.pdfbox.examples.pdmodel; 18 19 import org.apache.pdfbox.cos.COSDictionary; 20 import org.apache.pdfbox.exceptions.COSVisitorException; 21 import org.apache.pdfbox.pdmodel.PDDocument; 22 import org.apache.pdfbox.pdmodel.PDPage; 23 import org.apache.pdfbox.pdmodel.PDResources; 24 import org.apache.pdfbox.pdmodel.common.PDRectangle; 25 import org.apache.pdfbox.pdmodel.common.PDStream; 26 import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg; 27 import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm; 28 import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage; 29 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationRubberStamp; 30 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary; 31 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream; 32 import org.apache.pdfbox.util.MapUtil; 33 34 import java.io.FileInputStream; 35 import java.io.IOException; 36 import java.io.OutputStream; 37 import java.text.NumberFormat; 38 import java.util.ArrayList; 39 import java.util.List; 40 import java.util.Locale; 41 42 /** 43 * This is an example on how to add a rubber stamp with an image to pages of a PDF document. 44 * 45 * @version $Revision: 1.0 $ 46 */ 47 public class RubberStampWithImage 48 { 49 50 private static final String SAVE_GRAPHICS_STATE = "q\n"; 51 private static final String RESTORE_GRAPHICS_STATE = "Q\n"; 52 private static final String CONCATENATE_MATRIX = "cm\n"; 53 private static final String XOBJECT_DO = "Do\n"; 54 private static final String SPACE = " "; 55 56 private static NumberFormat formatDecimal = NumberFormat.getNumberInstance( Locale.US ); 57 58 /** 59 * Add a rubber stamp with an jpg image to every page of the given document. 60 * @param args the command line arguments 61 * @throws IOException an exception is thrown if something went wrong 62 */ 63 public void doIt( String[] args ) throws IOException 64 { 65 if( args.length != 3 ) 66 { 67 usage(); 68 } 69 else 70 { 71 PDDocument document = null; 72 try 73 { 74 document = PDDocument.load( args[0] ); 75 if( document.isEncrypted() ) 76 { 77 throw new IOException( "Encrypted documents are not supported for this example" ); 78 } 79 List allpages = new ArrayList(); 80 document.getDocumentCatalog().getPages().getAllKids(allpages); 81 int numberOfPages = allpages.size(); 82 83 for (int i=0; i < numberOfPages; i++) 84 { 85 PDPage apage = (PDPage) allpages.get(i); 86 List annotations = apage.getAnnotations(); 87 PDAnnotationRubberStamp rubberStamp = new PDAnnotationRubberStamp(); 88 rubberStamp.setName(PDAnnotationRubberStamp.NAME_TOP_SECRET); 89 rubberStamp.setRectangle(new PDRectangle(100,100)); 90 rubberStamp.setContents("A top secret note"); 91 92 // Create a PDXObjectImage with the given jpg 93 FileInputStream fin = new FileInputStream( args[2] ); 94 PDJpeg mypic = new PDJpeg(document,fin); 95 96 //Define and set the target rectangle 97 PDRectangle myrect = new PDRectangle(); 98 myrect.setUpperRightX(275); 99 myrect.setUpperRightY(575); 100 myrect.setLowerLeftX(250); 101 myrect.setLowerLeftY(550); 102 103 // Create a PDXObjectForm 104 PDStream formstream = new PDStream(document); 105 OutputStream os = formstream.createOutputStream(); 106 PDXObjectForm form = new PDXObjectForm(formstream); 107 form.setResources(new PDResources()); 108 form.setBBox(myrect); 109 form.setFormType(1); 110 // adjust the image to the target rectangle and add it to the stream 111 drawXObject(mypic, form.getResources(), os, 250, 550, 25, 25); 112 os.close(); 113 114 PDAppearanceStream myDic = new PDAppearanceStream(form.getCOSStream()); 115 PDAppearanceDictionary appearance = new PDAppearanceDictionary(new COSDictionary()); 116 appearance.setNormalAppearance(myDic); 117 rubberStamp.setAppearance(appearance); 118 rubberStamp.setRectangle(myrect); 119 120 //Add the new RubberStamp to the document 121 annotations.add(rubberStamp); 122 123 } 124 document.save( args[1] ); 125 } 126 catch(COSVisitorException exception) 127 { 128 System.err.println("An error occured during saving the document."); 129 System.err.println("Exception:"+exception); 130 } 131 finally 132 { 133 if( document != null ) 134 { 135 document.close(); 136 } 137 } 138 } 139 } 140 141 private void drawXObject( PDXObjectImage xobject, PDResources resources, OutputStream os, 142 float x, float y, float width, float height ) throws IOException 143 { 144 // This is similar to PDPageContentStream.drawXObject() 145 String xObjectPrefix = "Im"; 146 String objMapping = MapUtil.getNextUniqueKey( resources.getImages(), xObjectPrefix ); 147 resources.getXObjects().put( objMapping, xobject ); 148 149 appendRawCommands( os, SAVE_GRAPHICS_STATE ); 150 appendRawCommands( os, formatDecimal.format( width ) ); 151 appendRawCommands( os, SPACE ); 152 appendRawCommands( os, formatDecimal.format( 0 ) ); 153 appendRawCommands( os, SPACE ); 154 appendRawCommands( os, formatDecimal.format( 0 ) ); 155 appendRawCommands( os, SPACE ); 156 appendRawCommands( os, formatDecimal.format( height ) ); 157 appendRawCommands( os, SPACE ); 158 appendRawCommands( os, formatDecimal.format( x ) ); 159 appendRawCommands( os, SPACE ); 160 appendRawCommands( os, formatDecimal.format( y ) ); 161 appendRawCommands( os, SPACE ); 162 appendRawCommands( os, CONCATENATE_MATRIX ); 163 appendRawCommands( os, SPACE ); 164 appendRawCommands( os, "/" ); 165 appendRawCommands( os, objMapping ); 166 appendRawCommands( os, SPACE ); 167 appendRawCommands( os, XOBJECT_DO ); 168 appendRawCommands( os, SPACE ); 169 appendRawCommands( os, RESTORE_GRAPHICS_STATE ); 170 } 171 172 private void appendRawCommands(OutputStream os, String commands) throws IOException 173 { 174 os.write( commands.getBytes("ISO-8859-1")); 175 } 176 177 /** 178 * This creates an instance of RubberStampWithImage. 179 * 180 * @param args The command line arguments. 181 * 182 * @throws Exception If there is an error parsing the document. 183 */ 184 public static void main( String[] args ) throws Exception 185 { 186 RubberStampWithImage rubberStamp = new RubberStampWithImage(); 187 rubberStamp.doIt(args); 188 } 189 190 /** 191 * This will print the usage for this example. 192 */ 193 private void usage() 194 { 195 System.err.println( "Usage: java "+getClass().getName()+" <input-pdf> <output-pdf> <jpeg-filename>" ); 196 } 197 }