public void execute(CropParameters parameters) throws TaskException { PdfSource<?> source = parameters.getSource(); LOG.debug("Opening {} ", source); reader = source.open(sourceOpener); int totalPages = reader.getNumberOfPages(); File tmpFile = createTemporaryPdfBuffer(); LOG.debug("Created output temporary buffer {} ", tmpFile); copier = new DefaultPdfCopier(reader, tmpFile, parameters.getVersion()); copier.setCompression(parameters.isCompress()); copier.open(); Set<PdfRectangle> cropAreas = getPdfRectangles(parameters.getCropAreas()); for (int page = 1; page <= totalPages; page++) { for (PdfRectangle cropBox : cropAreas) { LOG.trace("Adding page {} with crop box {}", page, cropBox); copier.addPage(reader, page, cropBox); } notifyEvent(getNotifiableTaskMetadata()).stepsCompleted(page).outOf(totalPages); } copier.freeReader(reader); nullSafeCloseQuietly(copier); nullSafeClosePdfReader(reader); outputWriter.setOutput(file(tmpFile).name(parameters.getOutputName())); parameters.getOutput().accept(outputWriter); LOG.debug("Crop areas applied to {}", parameters.getOutput()); }
private Set<PdfRectangle> getPdfRectangles(Set<RectangularBox> areas) { Set<PdfRectangle> retVal = new LinkedHashSet<PdfRectangle>(); for (RectangularBox box : areas) { retVal.add(new PdfRectangle(box.getLeft(), box.getBottom(), box.getRight(), box.getTop())); } return retVal; }
public void addPage(PdfReader reader, int pageNumber, PdfRectangle cropBox) throws TaskException { PdfImportedPage page = pdfCopy.getImportedPage(reader, pageNumber); PdfDictionary dictionary = reader.getPageN(pageNumber); dictionary.put(PdfName.MEDIABOX, cropBox); dictionary.put(PdfName.CROPBOX, cropBox); addPage(page); }
@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; } }