/** * <a href="http://stackoverflow.com/questions/34394199/i-cant-rotate-my-page-from-existing-pdf"> * I can't rotate my page from existing PDF * </a> * <p> * Switching between portrait and landscape like this obviously will cut off some parts of the page. * </p> */ @Test public void testSwitchOrientation() throws DocumentException, IOException { try (InputStream resourceStream = getClass().getResourceAsStream("/mkl/testarea/itext5/extract/n2013.00849449.pdf")) { PdfReader reader = new PdfReader(resourceStream); int n = reader.getNumberOfPages(); PdfDictionary pageDict; for (int i = 1; i <= n; i++) { Rectangle rect = reader.getPageSize(i); Rectangle crop = reader.getCropBox(i); pageDict = reader.getPageN(i); pageDict.put(PdfName.MEDIABOX, new PdfArray(new float[] {rect.getBottom(), rect.getLeft(), rect.getTop(), rect.getRight()})); pageDict.put(PdfName.CROPBOX, new PdfArray(new float[] {crop.getBottom(), crop.getLeft(), crop.getTop(), crop.getRight()})); } PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(new File(RESULT_FOLDER, "n2013.00849449-switch.pdf"))); stamper.close(); reader.close(); } }
/** * These two methods ({@link #extractAttachments(PdfReader, String)} and * {@link #extractAttachment(PdfReader, File, PdfString, PdfDictionary)}) * essentially are the OP's original code posted in his question. They * extract files without the folder structure. */ public static void extractAttachments(PdfReader reader, String dir) throws IOException { File folder = new File(dir); folder.mkdirs(); PdfDictionary root = reader.getCatalog(); PdfDictionary names = root.getAsDict(PdfName.NAMES); System.out.println("" + names.getKeys().toString()); PdfDictionary embedded = names.getAsDict(PdfName.EMBEDDEDFILES); System.out.println("" + embedded.toString()); PdfArray filespecs = embedded.getAsArray(PdfName.NAMES); //System.out.println(filespecs.getAsString(root1)); for (int i = 0; i < filespecs.size();) { extractAttachment(reader, folder, filespecs.getAsString(i++), filespecs.getAsDict(i++)); } }
/** * <p> * These two methods ({@link #extractAttachmentsWithFolders(PdfReader, String)} and * {@link #extractAttachment(PdfReader, Map, PdfString, PdfDictionary)}) extend the * functionality of the OP's original code posted in his question. They extract files * with the folder structure. * </p> * <p> * The information concerning the portfolio folder structure is retrieved using * the method {@link #retrieveFolders(PdfReader, File)} and its helper method * {@link #collectFolders(Map, PdfDictionary, File)}. * </p> */ public static void extractAttachmentsWithFolders(PdfReader reader, String dir) throws IOException, DocumentException { File folder = new File(dir); folder.mkdirs(); Map<Integer, File> folders = retrieveFolders(reader, folder); PdfDictionary root = reader.getCatalog(); PdfDictionary names = root.getAsDict(PdfName.NAMES); System.out.println("" + names.getKeys().toString()); PdfDictionary embedded = names.getAsDict(PdfName.EMBEDDEDFILES); System.out.println("" + embedded.toString()); PdfArray filespecs = embedded.getAsArray(PdfName.NAMES); for (int i = 0; i < filespecs.size();) { extractAttachment(reader, folders, folder, filespecs.getAsString(i++), filespecs.getAsDict(i++)); } }
@Override public void renderText(TextRenderInfo renderInfo) { DocumentFont font =renderInfo.getFont(); PdfDictionary dict = font.getFontDictionary(); PdfDictionary encoding = dict.getAsDict(PdfName.ENCODING); PdfArray diffs = encoding.getAsArray(PdfName.DIFFERENCES); ; StringBuilder builder = new StringBuilder(); for (byte b : renderInfo.getPdfString().getBytes()) { PdfName name = diffs.getAsName((char)b); String s = name.toString().substring(2); int i = Integer.parseUnsignedInt(s, 16); builder.append((char)i); } try { stringField.set(renderInfo, builder.toString()); } catch (IllegalArgumentException | IllegalAccessException e) { e.printStackTrace(); } strategy.renderText(renderInfo); }
/** * <p> * A primitive attempt at copying links from page <code>sourcePage</code> * of <code>PdfReader reader</code> to page <code>targetPage</code> of * <code>PdfStamper stamper</code>. * </p> * <p> * This method is meant only for the use case at hand, i.e. copying a link * to an external URI without expecting any advanced features. * </p> */ void copyLinks(PdfStamper stamper, int targetPage, PdfReader reader, int sourcePage) { PdfDictionary sourcePageDict = reader.getPageNRelease(sourcePage); PdfArray annotations = sourcePageDict.getAsArray(PdfName.ANNOTS); if (annotations != null && annotations.size() > 0) { for (PdfObject annotationObject : annotations) { annotationObject = PdfReader.getPdfObject(annotationObject); if (!annotationObject.isDictionary()) continue; PdfDictionary annotation = (PdfDictionary) annotationObject; if (!PdfName.LINK.equals(annotation.getAsName(PdfName.SUBTYPE))) continue; PdfArray rectArray = annotation.getAsArray(PdfName.RECT); if (rectArray == null || rectArray.size() < 4) continue; Rectangle rectangle = PdfReader.getNormalizedRectangle(rectArray); PdfName hightLight = annotation.getAsName(PdfName.H); if (hightLight == null) hightLight = PdfAnnotation.HIGHLIGHT_INVERT; PdfDictionary actionDict = annotation.getAsDict(PdfName.A); if (actionDict == null || !PdfName.URI.equals(actionDict.getAsName(PdfName.S))) continue; PdfString urlPdfString = actionDict.getAsString(PdfName.URI); if (urlPdfString == null) continue; PdfAction action = new PdfAction(urlPdfString.toString()); PdfAnnotation link = PdfAnnotation.createLink(stamper.getWriter(), rectangle, hightLight, action); stamper.addAnnotation(link, targetPage); } } }
void show(FdfReader fdfReader) { PdfDictionary catalog = fdfReader.getCatalog(); catalog = catalog.getAsDict(PdfName.FDF); Assert.assertNotNull("FDF catalogue is null", catalog); PdfArray annots = catalog.getAsArray(PdfName.ANNOTS); Assert.assertNotNull("FDF annotations are null", annots); System.out.println(annots); }
/** * <a href="http://stackoverflow.com/questions/31402602/how-to-rename-only-the-first-found-duplicate-acrofield-in-pdf"> * How to rename only the first found duplicate acrofield in pdf? * </a> * <br> * <a href="http://s000.tinyupload.com/index.php?file_id=34970992934525199618"> * test_duplicate_field2.pdf * </a> * <p> * Demonstration of how to transform generate a new field for a widget. * </p> */ @Test public void testWidgetToField() throws IOException, DocumentException { try ( InputStream resource = getClass().getResourceAsStream("test_duplicate_field2.pdf"); OutputStream result = new FileOutputStream(new File(RESULT_FOLDER, "test_duplicate_field2-widgetToField.pdf")) ) { PdfReader reader = new PdfReader(resource); PdfDictionary form = reader.getCatalog().getAsDict(PdfName.ACROFORM); PdfArray fields = form.getAsArray(PdfName.FIELDS); for (PdfObject object: fields) { PdfDictionary field = (PdfDictionary) PdfReader.getPdfObject(object); if ("Text1".equals(field.getAsString(PdfName.T).toString())) { PdfDictionary newField = new PdfDictionary(); PRIndirectReference newFieldRef = reader.addPdfObject(newField); fields.add(newFieldRef); newField.putAll(field); newField.put(PdfName.T, new PdfString("foobar")); PdfArray newKids = new PdfArray(); newField.put(PdfName.KIDS, newKids); PdfArray kids = field.getAsArray(PdfName.KIDS); PdfObject widget = kids.remove(0); newKids.add(widget); PdfDictionary widgetDict = (PdfDictionary) PdfReader.getPdfObject(widget); widgetDict.put(PdfName.PARENT, newFieldRef); break; } } PdfStamper stamper = new PdfStamper(reader, result); stamper.close(); } }
/** * <a href="http://stackoverflow.com/questions/37275267/how-to-make-pdf-annotation-as-read-only-using-itext"> * how to make pdf annotation as read only using itext? * </a> * <br/> * test-annotated.pdf <i>simple PDF with sticky note</i> * * <p> * This test shows how to set the read-only flags of all annotations of a document. * </p> */ @Test public void testMarkAnnotationsReadOnly() throws IOException, DocumentException { try ( InputStream resourceStream = getClass().getResourceAsStream("test-annotated.pdf"); OutputStream outputStream = new FileOutputStream(new File(RESULT_FOLDER, "test-annotated-ro.pdf")) ) { PdfReader reader = new PdfReader(resourceStream); PdfStamper stamper = new PdfStamper(reader, outputStream); for (int page = 1; page <= reader.getNumberOfPages(); page++) { PdfDictionary pageDictionary = reader.getPageN(page); PdfArray annotationArray = pageDictionary.getAsArray(PdfName.ANNOTS); if (annotationArray == null) continue; for (PdfObject object : annotationArray) { PdfObject directObject = PdfReader.getPdfObject(object); if (directObject instanceof PdfDictionary) { PdfDictionary annotationDictionary = (PdfDictionary) directObject; PdfNumber flagsNumber = annotationDictionary.getAsNumber(PdfName.F); int flags = flagsNumber != null ? flagsNumber.intValue() : 0; flags |= PdfAnnotation.FLAGS_READONLY; annotationDictionary.put(PdfName.F, new PdfNumber(flags)); } } } stamper.close(); } }
@Test public void testWithStamper() throws DocumentException, IOException { InputStream resourceStream = getClass().getResourceAsStream("test.pdf"); try { PdfReader reader = new PdfReader(resourceStream); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(new File(RESULT_FOLDER, "test-trimmed-stamper.pdf"))); // Go through all pages int n = reader.getNumberOfPages(); for (int i = 1; i <= n; i++) { Rectangle pageSize = reader.getPageSize(i); Rectangle rect = getOutputPageSize(pageSize, reader, i); PdfDictionary page = reader.getPageN(i); page.put(PdfName.CROPBOX, new PdfArray(new float[]{rect.getLeft(), rect.getBottom(), rect.getRight(), rect.getTop()})); stamper.markUsed(page); } stamper.close(); } finally { if (resourceStream != null) resourceStream.close(); } }
@Test public void testWithStamperTopBottom() throws DocumentException, IOException { InputStream resourceStream = getClass().getResourceAsStream("test.pdf"); try { PdfReader reader = new PdfReader(resourceStream); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(new File(RESULT_FOLDER, "test-trimmed-stamper-top-bottom.pdf"))); // Go through all pages int n = reader.getNumberOfPages(); for (int i = 1; i <= n; i++) { Rectangle pageSize = reader.getPageSize(i); Rectangle rect = getOutputPageSize2(pageSize, reader, i); PdfDictionary page = reader.getPageN(i); page.put(PdfName.CROPBOX, new PdfArray(new float[]{rect.getLeft(), rect.getBottom(), rect.getRight(), rect.getTop()})); stamper.markUsed(page); } stamper.close(); } finally { if (resourceStream != null) resourceStream.close(); } }
@Test public void testWithStamperCentered() throws DocumentException, IOException { InputStream resourceStream = getClass().getResourceAsStream("test.pdf"); try { PdfReader reader = new PdfReader(resourceStream); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(new File(RESULT_FOLDER, "test-trimmed-stamper-centered.pdf"))); // Go through all pages int n = reader.getNumberOfPages(); for (int i = 1; i <= n; i++) { Rectangle pageSize = reader.getPageSize(i); Rectangle rect = getOutputPageSize3(pageSize, reader, i); PdfDictionary page = reader.getPageN(i); page.put(PdfName.CROPBOX, new PdfArray(new float[]{rect.getLeft(), rect.getBottom(), rect.getRight(), rect.getTop()})); stamper.markUsed(page); } stamper.close(); } finally { if (resourceStream != null) resourceStream.close(); } }
@Test public void testWithStamperExtFinder() throws DocumentException, IOException { InputStream resourceStream = getClass().getResourceAsStream("test.pdf"); try { PdfReader reader = new PdfReader(resourceStream); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(new File(RESULT_FOLDER, "test-trimmed-stamper-ext.pdf"))); // Go through all pages int n = reader.getNumberOfPages(); for (int i = 1; i <= n; i++) { Rectangle pageSize = reader.getPageSize(i); Rectangle rect = getOutputPageSize4(pageSize, reader, i); PdfDictionary page = reader.getPageN(i); page.put(PdfName.CROPBOX, new PdfArray(new float[]{rect.getLeft(), rect.getBottom(), rect.getRight(), rect.getTop()})); stamper.markUsed(page); } stamper.close(); } finally { if (resourceStream != null) resourceStream.close(); } }
/** * This methods creates a copy of the source document containing each page twice, * once with the cropbox limited to the left half page, once to the right one. */ void splitIntoHalfPages(InputStream source, File target) throws IOException, DocumentException { final PdfReader reader = new PdfReader(source); try ( OutputStream targetStream = new FileOutputStream(target) ) { Document document = new Document(); PdfCopy copy = new PdfCopy(document, targetStream); document.open(); for (int page = 1; page <= reader.getNumberOfPages(); page++) { PdfDictionary pageN = reader.getPageN(page); Rectangle cropBox = reader.getCropBox(page); PdfArray leftBox = new PdfArray(new float[]{cropBox.getLeft(), cropBox.getBottom(), (cropBox.getLeft() + cropBox.getRight()) / 2.0f, cropBox.getTop()}); PdfArray rightBox = new PdfArray(new float[]{(cropBox.getLeft() + cropBox.getRight()) / 2.0f, cropBox.getBottom(), cropBox.getRight(), cropBox.getTop()}); PdfImportedPage importedPage = copy.getImportedPage(reader, page); pageN.put(PdfName.CROPBOX, leftBox); copy.addPage(importedPage); pageN.put(PdfName.CROPBOX, rightBox); copy.addPage(importedPage); } document.close(); } finally { reader.close(); } }
/** * <a href="http://stackoverflow.com/questions/37027579/how-to-associate-a-previous-signature-in-a-new-signature-field"> * How to associate a previous signature in a new signature field * </a> * <br/> * <span>BLANK-signed.pdf, <em>a blank file from elsewhere with an invisible signature.</em></span> * <p> * Quite surprisingly it turns out that changing the signature appearance is possible without * breaking the signature, merely a warning appears which can be hidden by simply signing again. * </p> */ @Test public void testChangeAppearances() throws IOException, DocumentException { try ( InputStream resource = getClass().getResourceAsStream("BLANK-signed.pdf"); OutputStream result = new FileOutputStream(new File(RESULT_FOLDER, "BLANK-signed-app.pdf"))) { PdfReader pdfReader = new PdfReader(resource); PdfStamper pdfStamper = new PdfStamper(pdfReader, result, '\0', true); AcroFields acroFields = pdfStamper.getAcroFields(); for (String signatureName : acroFields.getSignatureNames()) { Item field = acroFields.getFieldItem(signatureName); field.writeToAll(PdfName.RECT, new PdfArray(new int[]{100,100,200,200}), Item.WRITE_WIDGET); field.markUsed(acroFields, Item.WRITE_WIDGET); PdfAppearance appearance = PdfAppearance.createAppearance(pdfStamper.getWriter(), 100, 100); appearance.setColorStroke(BaseColor.RED); appearance.moveTo(0, 0); appearance.lineTo(99, 99); appearance.moveTo(0, 99); appearance.lineTo(99, 0); appearance.stroke(); PdfDictionary appDict = new PdfDictionary(); appDict.put(PdfName.N, appearance.getIndirectReference()); field.writeToAll(PdfName.AP, appDict, Item.WRITE_WIDGET); } pdfStamper.close(); } }
/** * This method checks the signatures referenced from the AcroForm Fields. */ void verify(PdfReader reader) throws GeneralSecurityException { PdfDictionary top = (PdfDictionary)PdfReader.getPdfObjectRelease(reader.getCatalog().get(PdfName.ACROFORM)); if (top == null) { System.out.println("No AcroForm, so nothing to verify"); return; } PdfArray arrfds = (PdfArray)PdfReader.getPdfObjectRelease(top.get(PdfName.FIELDS)); if (arrfds == null || arrfds.isEmpty()) { System.out.println("No AcroForm Fields, so nothing to verify"); return; } for (PdfObject object : arrfds) { object = PdfReader.getPdfObject(object); if (object == null) { System.out.println("* A null entry."); } else if (!object.isDictionary()) { System.out.println("* A non-dictionary entry."); } else { verify(reader, (PdfDictionary) object, null, null, null, false); } } }
private static PdfArray createScaledBoxArray(final Rectangle scaledBox) { PdfArray scaleBoxArray = new PdfArray(); scaleBoxArray.add(new PdfNumber(scaledBox.getLeft())); scaleBoxArray.add(new PdfNumber(scaledBox.getBottom())); scaleBoxArray.add(new PdfNumber(scaledBox.getRight())); scaleBoxArray.add(new PdfNumber(scaledBox.getTop())); return scaleBoxArray; }
private Set<PdfDictionary> getFileAttachmentsDictionaries(PdfReader reader) { Set<PdfDictionary> retSet = new NullSafeSet<PdfDictionary>(); for (int k = 1; k <= reader.getNumberOfPages(); ++k) { PdfArray annots = reader.getPageN(k).getAsArray(PdfName.ANNOTS); if (annots != null) { for (PdfObject current : annots) { PdfDictionary annot = (PdfDictionary) PdfReader.getPdfObject(current); if (PdfName.FILEATTACHMENT.equals(annot.getAsName(PdfName.SUBTYPE))) { retSet.add(annot.getAsDict(PdfName.FS)); } } } } return retSet; }
/** * <a href="http://stackoverflow.com/questions/28911509/how-to-retain-page-labels-when-concatenating-an-existing-pdf-with-a-pdf-created"> * How to retain page labels when concatenating an existing pdf with a pdf created from scratch? * </a> * <p> * A proposal how to implement the task using a {@link PdfStamper}. */ @Test public void testInsertTitlePage() throws IOException, DocumentException { try ( InputStream documentStream = getClass().getResourceAsStream("Labels.pdf"); InputStream titleStream = getClass().getResourceAsStream("Cover.pdf"); OutputStream outputStream = new FileOutputStream(new File(RESULT_FOLDER, "labels-with-cover-page.pdf")) ) { PdfReader titleReader = new PdfReader(titleStream); PdfReader reader = new PdfReader(documentStream); PdfStamper stamper = new PdfStamper(reader, outputStream); PdfImportedPage page = stamper.getImportedPage(titleReader, 1); stamper.insertPage(1, titleReader.getPageSize(1)); PdfContentByte content = stamper.getUnderContent(1); content.addTemplate(page, 0, 0); copyLinks(stamper, 1, titleReader, 1); PdfDictionary root = reader.getCatalog(); PdfDictionary labels = root.getAsDict(PdfName.PAGELABELS); if (labels != null) { PdfArray newNums = new PdfArray(); newNums.add(new PdfNumber(0)); PdfDictionary coverDict = new PdfDictionary(); coverDict.put(PdfName.P, new PdfString("Cover Page")); newNums.add(coverDict); PdfArray nums = labels.getAsArray(PdfName.NUMS); if (nums != null) { for (int i = 0; i < nums.size() - 1; ) { int n = nums.getAsNumber(i++).intValue(); newNums.add(new PdfNumber(n+1)); newNums.add(nums.getPdfObject(i++)); } } labels.put(PdfName.NUMS, newNums); stamper.markUsed(labels); } stamper.close(); } }
boolean verify(PdfReader reader, PdfDictionary value) throws GeneralSecurityException { PdfArray byteRange = value.getAsArray(PdfName.BYTERANGE); if (byteRange == null || byteRange.isEmpty()) { System.out.printf(" Signed range: missing\n"); } else { StringBuilder builder = new StringBuilder(); builder.append(" Signed range:"); for (PdfObject arrObj: byteRange) { builder.append(' ').append(arrObj); } int byteRangeSize = byteRange.size(); if (byteRangeSize % 2 == 1) { builder.append(" (Invalid: odd number of entries)"); } else { StringBuilder interoperability = new StringBuilder(); if (byteRangeSize != 4) { interoperability.append(", not exactly one gap"); } int rangeStart = byteRange.getAsNumber(0).intValue(); if (rangeStart != 0) { interoperability.append(", first range does not start at 0"); } for (int i = 2; i < byteRangeSize; i+=2) { int lastRangeEnd = rangeStart + byteRange.getAsNumber(i-1).intValue(); rangeStart = byteRange.getAsNumber(i).intValue(); if (lastRangeEnd > rangeStart) { interoperability.append(", unordered or overlapping ranges"); break; } } if (interoperability.length() > 0) { builder.append(" (Interoperability issues").append(interoperability).append(')'); } int finalRangeEnd = byteRange.getAsNumber(byteRangeSize-2).intValue() + byteRange.getAsNumber(byteRangeSize-1).intValue(); if (finalRangeEnd == reader.getFileLength()) { builder.append(" (covers whole file)"); } else { builder.append(" (covers partial file up to ").append(finalRangeEnd).append(")"); } } System.out.println(builder); } PdfPKCS7 pkcs7 = verifySignature(reader, value, null); System.out.printf(" Validity: %s\n", pkcs7.verify()); return pkcs7 != null; }
@Override protected void configurePDFWriter(PdfWriter writer) throws IOException { double leftMap = pageFormat.getPageLeft(); double bottomMap = pageFormat.getPageBottom(); PdfDictionary lgiDict = new PdfDictionary(new PdfName("LGIDict")); lgiDict.put(new PdfName("Version"), new PdfNumber("2.1")); /* // Registration (optional): not interpreted by GDAL double rightMap = pageFormat.getPageRight(); double topMap = pageFormat.getPageTop(); float leftPage = xToPagePx((float) leftMap); float bottomPage = yToPagePx((float) bottomMap); float rightPage = xToPagePx((float) rightMap); float topPage = yToPagePx((float) topMap); PdfArray lowerLeftPoint = new PdfArray(); lowerLeftPoint.add(new PdfString(Double.toString(leftPage))); lowerLeftPoint.add(new PdfString(Double.toString(bottomPage))); lowerLeftPoint.add(new PdfString(Double.toString(leftMap))); lowerLeftPoint.add(new PdfString(Double.toString(bottomMap))); PdfArray upperRightPoint = new PdfArray(); upperRightPoint.add(new PdfString(Double.toString(rightPage))); upperRightPoint.add(new PdfString(Double.toString(topPage))); upperRightPoint.add(new PdfString(Double.toString(rightMap))); upperRightPoint.add(new PdfString(Double.toString(topMap))); PdfArray registration = new PdfArray(); registration.add(lowerLeftPoint); registration.add(upperRightPoint); lgiDict.put(new PdfName("Registration"), registration); */ // FIXME usage of PageFormat.MM2PX double scale = pageFormat.getPageWidthWorldCoordinates() / pageFormat.getPageWidth() / PageFormat.MM2PX; PdfArray ctmArray = new PdfArray(); ctmArray.add(new PdfString(Double.toString(scale))); ctmArray.add(new PdfString("0")); ctmArray.add(new PdfString("0")); ctmArray.add(new PdfString(Double.toString(scale))); ctmArray.add(new PdfString(Double.toString(leftMap))); ctmArray.add(new PdfString(Double.toString(bottomMap))); lgiDict.put(new PdfName("CTM"), ctmArray); // Projection PdfDictionary projectionDict = new PdfDictionary(new PdfName("Projection")); projectionDict.put(new PdfName("ProjectionType"), new PdfString("NONE")); lgiDict.put(new PdfName("Projection"), projectionDict); /* // Neatline (optional) PdfArray neatlinePoints = new PdfArray(); neatlinePoints.add(new PdfString(Double.toString(leftPage))); neatlinePoints.add(new PdfString(Double.toString(bottomPage))); neatlinePoints.add(new PdfString(Double.toString(rightPage))); neatlinePoints.add(new PdfString(Double.toString(topPage))); lgiDict.put(new PdfName("Neatline"), neatlinePoints); */ writer.addPageDictEntry(new PdfName("LGIDict"), lgiDict); }
@Override protected void configurePDFWriter(PdfWriter writer) throws IOException { final boolean initialPrecisionFlat = ByteBuffer.HIGH_PRECISION; try { ByteBuffer.HIGH_PRECISION = true; PdfDictionary dicMeasure = new PdfDictionary(new PdfName("Measure")); dicMeasure.put(PdfName.SUBTYPE, new PdfName("GEO")); PdfArray bounds = new PdfArray(); // lower left, upper left, upper right, lower right bounds.add(new float[]{0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f}); // geographic coordinates of corner points as lat/lon pairs PdfArray gpts = new PdfArray(lonLatCornerPoints); // lower left, upper left, upper right, lower right PdfArray lpts = new PdfArray(new float[]{0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f}); dicMeasure.put(new PdfName("Bounds"), bounds); dicMeasure.put(new PdfName("LPTS"), lpts); dicMeasure.put(new PdfName("GPTS"), gpts); PdfDictionary dicGCS = new PdfDictionary(new PdfName("PROJCS")); dicGCS.put(new PdfName("WKT"), new PdfString(wkt)); PdfIndirectObject indObjGCS = writer.addToBody(dicGCS); PdfIndirectReference indRefGCS = indObjGCS.getIndirectReference(); dicMeasure.put(new PdfName("GCS"), indRefGCS); PdfDictionary viewport = new PdfDictionary(new PdfName("Viewport")); viewport.put(new PdfName("Name"), new PdfString("Scree")); float left = (float) xToPagePx(pageFormat.getPageLeft()); float lower = (float) yToPagePx(pageFormat.getPageBottom()); float right = (float) xToPagePx(pageFormat.getPageRight()); float upper = (float) yToPagePx(pageFormat.getPageTop()); viewport.put(new PdfName("BBox"), new PdfRectangle(left, lower, right, upper)); PdfIndirectObject indObjMeasure = writer.addToBody(dicMeasure); PdfIndirectReference indRefMeasure = indObjMeasure.getIndirectReference(); viewport.put(new PdfName("Measure"), indRefMeasure); writer.setPageViewport(new PdfArray(viewport)); } finally { ByteBuffer.HIGH_PRECISION = initialPrecisionFlat; } }
private static void cropMultipliedFile(File source, CropJob cropJob) throws FileNotFoundException, DocumentException, IOException { PdfReader reader = new PdfReader(source.getAbsolutePath()); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(cropJob.getDestinationFile())); stamper.setMoreInfo(cropJob.getSourceMetaInfo()); PdfDictionary pageDict; int newPageNumber = 1; for (int origPageNumber = 1; origPageNumber <= cropJob.getSourcePageCount(); origPageNumber++) { SingleCluster cluster = cropJob.getClusterCollection().getSingleCluster(origPageNumber); // if no crop was selected do nothing if (cluster.getRatiosList().size() == 0) { newPageNumber++; continue; } for (Float[] ratios : cluster.getRatiosList()) { pageDict = reader.getPageN(newPageNumber); List<Rectangle> boxes = new ArrayList<Rectangle>(); boxes.add(reader.getBoxSize(newPageNumber, "media")); boxes.add(reader.getBoxSize(newPageNumber, "crop")); int rotation = reader.getPageRotation(newPageNumber); Rectangle scaledBox = calculateScaledRectangle(boxes, ratios, rotation); PdfArray scaleBoxArray = new PdfArray(); scaleBoxArray.add(new PdfNumber(scaledBox.getLeft())); scaleBoxArray.add(new PdfNumber(scaledBox.getBottom())); scaleBoxArray.add(new PdfNumber(scaledBox.getRight())); scaleBoxArray.add(new PdfNumber(scaledBox.getTop())); pageDict.put(PdfName.CROPBOX, scaleBoxArray); pageDict.put(PdfName.MEDIABOX, scaleBoxArray); // increment the pagenumber newPageNumber++; } int[] range = new int[2]; range[0] = newPageNumber - 1; range[1] = cropJob.getSourcePageCount() + (newPageNumber - origPageNumber); SimpleBookmark.shiftPageNumbers(cropJob.getSourceBookmarks(), cluster.getRatiosList().size() - 1, range); } stamper.setOutlines(cropJob.getSourceBookmarks()); stamper.close(); reader.close(); }
private static void cropMultipliedFile(final CropDefinition cropDefinition, final File multipliedDocument, final PdfMetaInformation pdfMetaInformation) throws DocumentException, IOException { PdfReader reader = new PdfReader(multipliedDocument.getAbsolutePath()); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(cropDefinition.getDestinationFile())); stamper.setMoreInfo(pdfMetaInformation.getSourceMetaInfo()); PdfDictionary pageDict; int newPageNumber = 1; for (int sourcePageNumber = 1; sourcePageNumber <= pdfMetaInformation.getSourcePageCount(); sourcePageNumber++) { List<Float[]> rectangleList = cropDefinition.getRectanglesForPage(sourcePageNumber); // if no crop was selected do nothing if (rectangleList.isEmpty()) { newPageNumber++; continue; } for (Float[] ratios : rectangleList) { pageDict = reader.getPageN(newPageNumber); List<Rectangle> boxes = new ArrayList<Rectangle>(); boxes.add(reader.getBoxSize(newPageNumber, "media")); boxes.add(reader.getBoxSize(newPageNumber, "crop")); int rotation = reader.getPageRotation(newPageNumber); Rectangle scaledBox = RectangleHandler.calculateScaledRectangle(boxes, ratios, rotation); PdfArray scaleBoxArray = createScaledBoxArray(scaledBox); pageDict.put(PdfName.CROPBOX, scaleBoxArray); pageDict.put(PdfName.MEDIABOX, scaleBoxArray); // increment the pagenumber newPageNumber++; } int[] range = new int[2]; range[0] = newPageNumber - 1; range[1] = pdfMetaInformation.getSourcePageCount() + (newPageNumber - sourcePageNumber); SimpleBookmark.shiftPageNumbers(pdfMetaInformation.getSourceBookmarks(), rectangleList.size() - 1, range); } stamper.setOutlines(pdfMetaInformation.getSourceBookmarks()); stamper.close(); reader.close(); }
@Override public void exportElement(JRPdfExporterContext exporterContext, JRGenericPrintElement element) { try { PdfWriter writer = exporterContext.getPdfWriter(); PdfIndirectObject swfRef; boolean newContext = !existingContexts.containsKey(exporterContext); if (newContext) { PdfDictionary extensions = new PdfDictionary(); PdfDictionary adobeExtension = new PdfDictionary(); adobeExtension.put(new PdfName("BaseVersion"), PdfWriter.PDF_VERSION_1_7); adobeExtension.put(new PdfName("ExtensionLevel"), new PdfNumber(3)); extensions.put(new PdfName("ADBE"), adobeExtension); writer.getExtraCatalog().put(new PdfName("Extensions"), extensions); byte[] swfData = getChartSwf(); PdfFileSpecification swfFile = PdfFileSpecification.fileEmbedded(writer, null, "Open Flash Chart", swfData); swfRef = writer.addToBody(swfFile); existingContexts.put(exporterContext, swfRef); } else { swfRef = (PdfIndirectObject) existingContexts.get(exporterContext); } Rectangle rect = new Rectangle(element.getX() + exporterContext.getOffsetX(), exporterContext.getExportedReport().getPageHeight() - element.getY() - exporterContext.getOffsetY(), element.getX() + exporterContext.getOffsetX() + element.getWidth(), exporterContext.getExportedReport().getPageHeight() - element.getY() - exporterContext.getOffsetY() - element.getHeight()); PdfAnnotation ann = new PdfAnnotation(writer, rect); ann.put(PdfName.SUBTYPE, new PdfName("RichMedia")); PdfDictionary settings = new PdfDictionary(); PdfDictionary activation = new PdfDictionary(); activation.put(new PdfName("Condition"), new PdfName("PV")); settings.put(new PdfName("Activation"), activation); ann.put(new PdfName("RichMediaSettings"), settings); PdfDictionary content = new PdfDictionary(); HashMap<String, PdfIndirectReference> assets = new HashMap<String, PdfIndirectReference>(); assets.put("map.swf", swfRef.getIndirectReference()); PdfDictionary assetsDictionary = PdfNameTree.writeTree(assets, writer); content.put(new PdfName("Assets"), assetsDictionary); PdfArray configurations = new PdfArray(); PdfDictionary configuration = new PdfDictionary(); PdfArray instances = new PdfArray(); PdfDictionary instance = new PdfDictionary(); instance.put(new PdfName("Subtype"), new PdfName("Flash")); PdfDictionary params = new PdfDictionary(); String chartData = ((ChartGenerator) element.getParameterValue(ChartGenerator.PARAMETER_CHART_GENERATOR)).generateChart(); String vars = "inline_data=" + chartData; params.put(new PdfName("FlashVars"), new PdfString(vars)); instance.put(new PdfName("Params"), params); instance.put(new PdfName("Asset"), swfRef.getIndirectReference()); PdfIndirectObject instanceRef = writer.addToBody(instance); instances.add(instanceRef.getIndirectReference()); configuration.put(new PdfName("Instances"), instances); PdfIndirectObject configurationRef = writer.addToBody(configuration); configurations.add(configurationRef.getIndirectReference()); content.put(new PdfName("Configurations"), configurations); ann.put(new PdfName("RichMediaContent"), content); writer.addAnnotation(ann); } catch (Exception e) { throw new RuntimeException(e); } }
/** * <p> * This method restricts the media boxes of the pages in the given {@link PdfReader} * to the actual content found by the {@link MarginFinder} extended render listener. * </p> * <p> * It essentially is copied from the {@link TestTrimPdfPage} methods * {@link TestTrimPdfPage#testWithStamperExtFinder()} and * {@link TestTrimPdfPage#getOutputPageSize4(Rectangle, PdfReader, int)}. * In contrast to the code there this method manipulates * the media box because this is the only box respected by * {@link PdfWriter#getImportedPage(PdfReader, int)}. * </p> */ static void cropPdf(PdfReader reader) throws IOException { int n = reader.getNumberOfPages(); for (int i = 1; i <= n; i++) { PdfReaderContentParser parser = new PdfReaderContentParser(reader); MarginFinder finder = parser.processContent(i, new MarginFinder()); Rectangle rect = new Rectangle(finder.getLlx(), finder.getLly(), finder.getUrx(), finder.getUry()); PdfDictionary page = reader.getPageN(i); page.put(PdfName.MEDIABOX, new PdfArray(new float[]{rect.getLeft(), rect.getBottom(), rect.getRight(), rect.getTop()})); } }