@Override public WatermarkParameters toTaskParameters(WatermarkTaskCliArguments args) { WatermarkParameters parameters = new WatermarkParameters(args.getWatermark().getSource()); if (args.isDimension()) { parameters.setDimension(args.getDimension().getDimension()); } parameters.setLocation(args.getLocation().getEnumValue()); parameters.setOpacity(args.getAlpha()); parameters.setPosition(args.getPosition().getPoint()); if (args.isPageSelection()) { parameters.addAllPageRanges(args.getPageSelection().getPageRangeSet()); } populateAbstractParameters(parameters, args); populateSourceParameters(parameters, args); populateOutputTaskParameters(parameters, args); populateOutputPrefix(parameters, args); return parameters; } }
@Test public void getPages() { WatermarkParameters victim = new WatermarkParameters(StreamSource.newInstance(mock(InputStream.class), "name")); victim.addPageRange(new PageRange(5, 8)); victim.addPageRange(new PageRange(3, 3)); victim.addPageRange(new PageRange(10)); Set<Integer> pages = victim.getPages(11); assertThat(pages, contains(5, 6, 7, 8, 3, 10, 11)); assertThat(pages, not(contains(1, 2, 4, 9))); }
private void setUpParams(WatermarkParameters parameters, PdfSource<?> source) throws IOException { parameters.setCompress(true); parameters.setPosition(new Point(10, 50)); parameters.setOpacity(40); testContext.directoryOutputTo(parameters); parameters.setOutputPrefix("test_file[FILENUMBER]"); parameters.addSource(source); parameters.setExistingOutputPolicy(ExistingOutputPolicy.OVERWRITE); }
@Test public void testEquals() { FileSource source = mock(FileSource.class); WatermarkParameters eq1 = new WatermarkParameters(source); eq1.setOpacity(50); WatermarkParameters eq2 = new WatermarkParameters(source); eq2.setOpacity(50); WatermarkParameters eq3 = new WatermarkParameters(source); eq3.setOpacity(50); WatermarkParameters diff = new WatermarkParameters(source); diff.setOpacity(50); diff.setLocation(Location.OVER); TestUtils.testEqualsAndHashCodes(eq1, eq2, eq3, diff); }
public void mark(PDPage page) throws TaskIOException { PDExtendedGraphicsState gs = null; if (parameters.getOpacity() != 100) { gs = new PDExtendedGraphicsState(); float alpha = (float) parameters.getOpacity() / 100; gs.setStrokingAlphaConstant(alpha); gs.setNonStrokingAlphaConstant(alpha); } if (parameters.getLocation() == Location.BEHIND) { imageWriter.prepend(page, form, page.cropBoxCoordinatesToDraw(parameters.getPosition()), 1, 1, gs, page.getRotation()); } else { imageWriter.append(page, form, page.cropBoxCoordinatesToDraw(parameters.getPosition()), 1, 1, gs, page.getRotation()); } }
@Test public void testRotated270CropOffset() throws Exception { WatermarkParameters parameters = pngParams(customInput("pdf/rotation_270_cropped_test_file.pdf")); parameters.addPageRange(new PageRange(1, 3)); parameters.setPosition(new Point(5, 10)); parameters.setDimension(new Dimension(194, 87)); parameters.setOpacity(100); execute(parameters); testContext.assertTaskCompleted(); testContext.forPdfOutput(d -> { assertNotNull(d.getPage(1).getResources().getCOSObject().getDictionaryObject(COSName.XOBJECT, COSDictionary.class)); assertNotNull(d.getPage(2).getResources().getCOSObject().getDictionaryObject(COSName.XOBJECT, COSDictionary.class)); assertImageAtLocation(d, d.getPage(1), new Rectangle(49, 785, 194, 87)); assertImageAtLocation(d, d.getPage(1), new Rectangle(49, 785, 194, 87)); assertImageAtLocation(d, d.getPage(2), new Rectangle(49, 785, 194, 87)); assertNoImageAtLocation(d, d.getPage(3), new Rectangle(49, 785, 194, 87)); }); }
private WatermarkParameters pngParams(PdfSource<?> source) throws IOException { WatermarkParameters parameters = new WatermarkParameters(customNonPdfInput("image/black-rect.png")); setUpParams(parameters, source); parameters.setDimension(new Dimension(248, 103)); return parameters; }
@Test public void invalidParametersOpacity() { WatermarkParameters victim = new WatermarkParameters(StreamSource.newInstance(mock(InputStream.class), "name")); PdfSource<InputStream> input = PdfStreamSource.newInstanceNoPassword(mock(InputStream.class), "name"); victim.addSource(input); SingleOrMultipleTaskOutput output = mock(SingleOrMultipleTaskOutput.class); victim.setOutput(output); victim.setOpacity(-1); TestUtils.assertInvalidParameters(victim); }
@Test public void invalidParametersImageSize() { WatermarkParameters victim = new WatermarkParameters(StreamSource.newInstance(mock(InputStream.class), "name")); victim.setDimension(new Dimension(-300, 300)); PdfSource<InputStream> input = PdfStreamSource.newInstanceNoPassword(mock(InputStream.class), "name"); victim.addSource(input); SingleOrMultipleTaskOutput output = mock(SingleOrMultipleTaskOutput.class); victim.setOutput(output); TestUtils.assertInvalidParameters(victim); }
@Test public void testOpacity() throws IOException { WatermarkParameters parameters = pngParams(customInput("pdf/test_file.pdf")); parameters.addPageRange(new PageRange(1, 1)); parameters.setLocation(Location.BEHIND); parameters.setOpacity(30); execute(parameters); testContext.assertTaskCompleted(); testContext.forPdfOutput(d -> { PDStream formPrintStream = d.getPage(0).getContentStreams().next(); try (ContentStreamParser parser = new ContentStreamParser( SeekableSources.inMemorySeekableSourceFrom(formPrintStream.createInputStream()))) { List<Object> tokens = parser.tokens(); assertEquals(13, tokens.size()); assertEquals("gs1", ((COSName) tokens.get(8)).getName()); assertEquals("gs", ((Operator) tokens.get(9)).getName()); } catch (IOException e) { fail(e.getMessage()); } }); }
@Test public void testImageNegativeRotation() throws Exception { WatermarkParameters parameters = new WatermarkParameters(customNonPdfInput("image/draft.png")); setUpParams(parameters, customInput("pdf/test_file.pdf")); parameters.setDimension(new Dimension(200, 83)); parameters.setRotationDegrees(-315); execute(parameters); testContext.assertTaskCompleted(); testContext.forPdfOutput(d -> { assertImageAtLocation(d, d.getPage(0), new Rectangle(68, -8, 200, 83)); }); }
int currentStep = 0; for (PdfSource<?> source : parameters.getSourceList()) { executionContext().assertTaskNotCancelled(); currentStep++; documentHandler.setCreatorOnPDDocument(); File tmpFile = createTemporaryBuffer(parameters.getOutput()); LOG.debug("Created output on temporary buffer {}", tmpFile); for (Integer page : parameters.getPages(documentHandler.getNumberOfPages())) { executionContext().assertTaskNotCancelled(); try { documentHandler.setVersionOnPDDocument(parameters.getVersion()); documentHandler.setCompress(parameters.isCompress()); documentHandler.savePDDocument(tmpFile); String outName = nameGenerator(parameters.getOutputPrefix()) .generate(nameRequest().originalName(source.getName()).fileNumber(currentStep)); outputWriter.addOutput(file(tmpFile).name(outName)); parameters.getOutput().accept(outputWriter); LOG.debug("Input documents watermarked and written to {}", parameters.getOutput());
@Test public void testAddingPngImageScaled() throws Exception { WatermarkParameters parameters = new WatermarkParameters(customNonPdfInput("image/black-rect.png")); setUpParams(parameters, customInput("pdf/test_file.pdf")); parameters.setDimension(new Dimension(200, 83)); parameters.addPageRange(new PageRange(1, 1)); execute(parameters); testContext.assertTaskCompleted(); testContext.forPdfOutput(d -> { assertNotNull(d.getPage(0).getResources().getCOSObject().getDictionaryObject(COSName.XOBJECT, COSDictionary.class)); assertImageAtLocation(d, d.getPage(0), new Rectangle(10, 50, 200, 83)); assertNoImageAtLocation(d, d.getPage(1), new Rectangle(10, 50, 200, 83)); assertNoImageAtLocation(d, d.getPage(2), new Rectangle(10, 50, 200, 83)); assertNoImageAtLocation(d, d.getPage(3), new Rectangle(10, 50, 200, 83)); }); }
@Test public void invalidParametersEmptyWatermark() { WatermarkParameters victim = new WatermarkParameters(null); PdfSource<InputStream> input = PdfStreamSource.newInstanceNoPassword(mock(InputStream.class), "name"); victim.addSource(input); SingleOrMultipleTaskOutput output = mock(SingleOrMultipleTaskOutput.class); victim.setOutput(output); TestUtils.assertInvalidParameters(victim); }
@Test public void testCropOffset() throws Exception { WatermarkParameters parameters = pngParams(customInput("pdf/cropped_test_file.pdf")); parameters.addPageRange(new PageRange(2, 3)); parameters.setPosition(new Point(0, 10)); parameters.setDimension(new Dimension(200, 90)); execute(parameters); testContext.assertTaskCompleted(); testContext.forPdfOutput(d -> { assertNotNull(d.getPage(1).getResources().getCOSObject().getDictionaryObject(COSName.XOBJECT, COSDictionary.class)); assertNotNull(d.getPage(2).getResources().getCOSObject().getDictionaryObject(COSName.XOBJECT, COSDictionary.class)); assertNoImageAtLocation(d, d.getPage(0), new Rectangle(36, 50, 200, 90)); assertImageAtLocation(d, d.getPage(1), new Rectangle(36, 50, 200, 90)); assertImageAtLocation(d, d.getPage(2), new Rectangle(36, 50, 200, 90)); assertNoImageAtLocation(d, d.getPage(3), new Rectangle(36, 50, 200, 90)); }); }
public PdfWatermarker(WatermarkParameters parameters, PDDocument document) throws TaskIOException { this.imageWriter = new PageImageWriter(document); this.parameters = parameters; PDImageXObject watermark = PageImageWriter.toPDXImageObject(parameters.getWatermark()); form = new PDFormXObject(); form.setResources(new PDResources()); PDTransparencyGroupAttributes group = new PDTransparencyGroupAttributes(); group.setKnockout(); this.form.setGroup(group); PDRectangle bbox = ofNullable(parameters.getDimension()) .map(d -> new PDRectangle((float) d.getWidth(), (float) d.getHeight())) .orElseGet(() -> new PDRectangle(watermark.getWidth(), watermark.getHeight())); form.setBBox(bbox); int degrees = parameters.getRotationDegrees() % 360; if (degrees < 0) { degrees += 360; } if (degrees != 0) { AffineTransform at = form.getMatrix().createAffineTransform(); at.rotate(toRadians(degrees), bbox.getWidth() / 2, bbox.getHeight() / 2); form.setMatrix(at); } try (PDPageContentStream contentStream = new PDPageContentStream(document, form)) { contentStream.drawImage(watermark, 0, 0, form.getBBox().getWidth(), form.getBBox().getHeight()); } catch (IOException e) { throw new TaskIOException("An error occurred writing form xobject stream.", e); } }
@Test public void testNoOpacity() throws IOException { WatermarkParameters parameters = pngParams(regularInput()); parameters.addPageRange(new PageRange(1, 1)); parameters.setLocation(Location.BEHIND); execute(parameters); testContext.assertTaskCompleted(); testContext.forPdfOutput(d -> { PDStream formPrintStream = d.getPage(0).getContentStreams().next(); try (ContentStreamParser parser = new ContentStreamParser( SeekableSources.inMemorySeekableSourceFrom(formPrintStream.createInputStream()))) { parser.tokens().stream().filter(t -> t instanceof Operator).map(t -> (Operator) t) .noneMatch(o -> "gs".equals(o.getName())); } catch (IOException e) { fail(e.getMessage()); } }); }
@Test public void testDefaults() { WatermarkParameters parameters = defaultCommandLine().invokeSejdaConsole(); assertEquals(Location.BEHIND, parameters.getLocation()); assertEquals(100, parameters.getOpacity()); } }
@Test public void testAddingPngImage() throws Exception { WatermarkParameters parameters = pngParams(customInput("pdf/test_file.pdf")); parameters.addPageRange(new PageRange(2, 3)); execute(parameters); testContext.assertTaskCompleted(); testContext.forPdfOutput(d -> { assertNotNull(d.getPage(1).getResources().getCOSObject().getDictionaryObject(COSName.XOBJECT, COSDictionary.class)); assertNotNull(d.getPage(2).getResources().getCOSObject().getDictionaryObject(COSName.XOBJECT, COSDictionary.class)); assertNoImageAtLocation(d, d.getPage(0), new Rectangle(10, 50, 248, 103)); assertImageAtLocation(d, d.getPage(1), new Rectangle(10, 50, 248, 103)); assertImageAtLocation(d, d.getPage(2), new Rectangle(10, 50, 248, 103)); assertNoImageAtLocation(d, d.getPage(3), new Rectangle(10, 50, 248, 103)); }); }
@Test public void testDimension() { WatermarkParameters parameters = defaultCommandLine().with("-d", "200x55").invokeSejdaConsole(); assertEquals(200, parameters.getDimension().getWidth(), 0); assertEquals(55, parameters.getDimension().getHeight(), 0); }