How to add watermarks to PDFs using Java

Table of contents

    How to add watermarks to PDFs using Java
    Summary

    Learn how to use our Java PDF library to add professional watermarks to PDF documents with precise control over positioning, styling, and page ranges. This comprehensive guide demonstrates how to integrate watermarking capabilities into Java applications, including dynamic text, page numbers, and custom formatting options. Discover how our flexible watermarking system enables multiple watermarks per page while supporting various page types and dynamic field codes.

    Nutrient Document Converter Services contains a flexible system for applying watermarks to documents. Multiple watermarks can be applied to the same page, and watermarks can be applied to page ranges or certain page types such as odd, even, portrait, or landscape. In addition, you can add field codes such as {PAGE} and {NUMPAGES} to dynamically add page numbers, headers, and footers to PDF documents.

    Watermarks are passed as part of the ConversionSettings object, a parameter of the Convert method. An overview of the watermarking-related web services interface is provided below. For full details, refer to our guidebooks.

    ClassDiagram-Watermarking(opens in a new tab)

    The following Java-based sample code is identical to a previous sample, with the exception that the Watermarks property in the ConversionSettings class is populated with a simple watermark that prints the word Confidential on the front page in combination with the current date. Note that this sample code is automatically installed with the conversion service.

    For details on how to set up your Java environment and generate the web service proxies see this post.

    `package com.muhimbi.app;
    import com.muhimbi.ws.*;
    import java.io.*;
    import java.net.URL;
    import java.util.List;
    import javax.xml.bind.JAXBElement;
    import javax.xml.namespace.QName;
    public class WsClient {
    private final static String DOCUMENTCONVERTERSERVICE_WSDL_LOCATION =
            "https://localhost:41734/Muhimbi.DocumentConverter.WebService/?wsdl";
    public static void main(String[] args) {
        try {
          if (args.length != 1) {
            System.out.println("Please specify a single file name on the command line.");
          } else {
            // ** Process command line parameters
            String sourceDocumentPath = args[0];
            File file = new File(sourceDocumentPath);
            String fileName = getFileName(file);
            String fileExt = getFileExtension(file);
            System.out.println("Converting file " + sourceDocumentPath);
            // ** Initialise Web Service
            DocumentConverterService_Service dcss = new DocumentConverterService_Service(
                new URL(DOCUMENTCONVERTERSERVICE_WSDL_LOCATION),
                new QName("https://tempuri.org/", "DocumentConverterService"));
            DocumentConverterService dcs = dcss.getBasicHttpBindingDocumentConverterService();
            // ** Only call conversion if file extension is supported
            if (isFileExtensionSupported(fileExt, dcs)) {
              // ** Read source file from disk
              byte[] fileContent = readFile(sourceDocumentPath);
              // ** Converting the file
              OpenOptions openOptions = getOpenOptions(fileName, fileExt);
              ConversionSettings conversionSettings = getConversionSettings();
              byte[] convertedFile = dcs.convert(fileContent, openOptions, conversionSettings);
              // ** Writing converted file to file system
              String destinationDocumentPath = getPDFDocumentPath(file);
              writeFile(convertedFile, destinationDocumentPath);
              System.out.println("File converted sucessfully to " + destinationDocumentPath);
            } else {
              System.out.println("The file extension is not supported.");
            }
          }
        } catch (IOException e) {
          System.out.println(e.getMessage());
        } catch (DocumentConverterServiceGetConfigurationWebServiceFaultExceptionFaultFaultMessage e) {
          printException(e.getFaultInfo());
        } catch (DocumentConverterServiceConvertWebServiceFaultExceptionFaultFaultMessage e) {
          printException(e.getFaultInfo());
        }
    }
    public static OpenOptions getOpenOptions(String fileName, String fileExtension) {
        ObjectFactory objectFactory = new ObjectFactory();
        OpenOptions openOptions = new OpenOptions();
        // ** Set the minimum required open options. Additional options are available
        openOptions.setOriginalFileName(objectFactory.createOpenOptionsOriginalFileName(fileName));
        openOptions.setFileExtension(objectFactory.createOpenOptionsFileExtension(fileExtension));
        return openOptions;
    }
    public static ConversionSettings getConversionSettings() {
        ConversionSettings conversionSettings = new ConversionSettings();
        // ** Set the minimum required conversion settings. Additional settings are available
        conversionSettings.setQuality(ConversionQuality.OPTIMIZE_FOR_PRINT);
        conversionSettings.setRange(ConversionRange.ALL_DOCUMENTS);
        conversionSettings.getFidelity().add("Full");
        conversionSettings.setFormat(OutputFormat.PDF);
        conversionSettings.setWatermarks(getWatermarks());
        return conversionSettings;
    }
    public static JAXBElement<ArrayOfWatermark> getWatermarks()
    {
        ObjectFactory objectFactory = new ObjectFactory();
        ArrayOfWatermark watermarks = new ArrayOfWatermark();
        // ** Specify some of the default settings for properties
        Defaults wmDefaults = new Defaults();
        wmDefaults.setFillColor(objectFactory.createDefaultsFillColor("#FF0000"));
        wmDefaults.setFontFamilyName(objectFactory.createDefaultsFontFamilyName("Arial"));
        // ** 'Confidential' watermark for front page
        Watermark confidential = new Watermark();
        confidential.setDefaults(objectFactory.createContainerDefaults(wmDefaults));
        confidential.setStartPage(1);
        confidential.setEndPage(1);
        confidential.setRotation(objectFactory.createElementRotation("-15"));
        confidential.setWidth(objectFactory.createElementWidth("500"));
        confidential.setHeight(objectFactory.createElementHeight("250"));
        confidential.setHPosition(HPosition.CENTER);
        confidential.setVPosition(VPosition.ABSOLUTE);
        confidential.setY(objectFactory.createElementY("275"));
        confidential.setZOrder(-1);
        // ** Create a new Text element that goes inside the watermark
        Text cfText = new Text();
        cfText.setContent(objectFactory.createTextContent("Confidential - {DATE}"));
        cfText.setFontSize(objectFactory.createTextFontSize("40"));
        cfText.getFontStyle().add("Bold");
        cfText.getFontStyle().add("Italic");
        cfText.setWidth(objectFactory.createElementWidth("500"));
        cfText.setHeight(objectFactory.createElementHeight("250"));
        cfText.setTransparency(objectFactory.createElementTransparency("0.10"));
        // ** And add it to the list of watermark elements.
        ArrayOfElement cfElements = new ArrayOfElement();
        cfElements.getElement().add(cfText);
        confidential.setElements(objectFactory.createContainerElements(cfElements));
        // ** And add the watermark to the list of watermarks
        watermarks.getWatermark().add(confidential);
        return objectFactory.createConversionSettingsWatermarks(watermarks);
    }
    public static String getFileName(File file) {
        String fileName = file.getName();
        return fileName.substring(0, fileName.lastIndexOf('.'));
    }
    public static String getFileExtension(File file) {
        String fileName = file.getName();
        return fileName.substring(fileName.lastIndexOf('.') + 1, fileName.length());
    }
    public static String getPDFDocumentPath(File file) {
        String fileName = getFileName(file);
        String folder = file.getParent();
        if (folder == null) {
          folder = new File(file.getAbsolutePath()).getParent();
        }
        return folder + File.separatorChar + fileName + '.' + OutputFormat.PDF.value();
    }
    public static byte[] readFile(String filepath) throws IOException {
        File file = new File(filepath);
        InputStream is = new FileInputStream(file);
        long length = file.length();
        byte[] bytes = new byte[(int) length];
        int offset = 0;
        int numRead;
        while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
          offset += numRead;
        }
        if (offset < bytes.length) {
          throw new IOException("Could not completely read file " + file.getName());
        }
        is.close();
        return bytes;
    }
    public static void writeFile(byte[] fileContent, String filepath) throws IOException {
        OutputStream os = new FileOutputStream(filepath);
        os.write(fileContent);
        os.close();
    }
    public static boolean isFileExtensionSupported(String extension, DocumentConverterService dcs)
        throws DocumentConverterServiceGetConfigurationWebServiceFaultExceptionFaultFaultMessage
        {
          Configuration configuration = dcs.getConfiguration();
          final JAXBElement<ArrayOfConverterConfiguration> converters = configuration.getConverters();
          final ArrayOfConverterConfiguration ofConverterConfiguration = converters.getValue();
          final List<ConverterConfiguration> cList = ofConverterConfiguration.getConverterConfiguration();
          for (ConverterConfiguration cc : cList) {
            final List<String> supportedExtension = cc.getSupportedFileExtensions().getValue().getString();
            if (supportedExtension.contains(extension)) {
              return true;
            }
        }
        return false;
    }
    public static void printException(WebServiceFaultException serviceFaultException) {
        System.out.println(serviceFaultException.getExceptionType());
        JAXBElement<ArrayOfstring> element = serviceFaultException.getExceptionDetails();
        ArrayOfstring value = element.getValue();
        for (String msg : value.getString()) {
          System.out.println(msg);
        }
    }
    }`

    Conclusion

    Adding watermarks to PDF documents using Nutrient Document Converter Services in a Java environment is not only possible — it’s highly customizable and powerful. With support for dynamic fields like {DATE} and {PAGE}, as well as detailed control over positioning, styling, and layering, developers can implement everything from simple Confidential marks to fully styled headers and footers.

    By extending the standard document conversion process with watermarking via the ConversionSettings object, teams working in Java can bring professional-grade output to their applications with no .NET knowledge required.

    Clavin Fernandes

    Clavin Fernandes

    Developer Relations and Support Services

    Clavin is a Microsoft Business Applications MVP who supports 1,000+ high-level enterprise customers with challenges related to PDF conversion in combination with SharePoint on-premises Office 365, Azure, Nintex, K2, and Power Platform mostly no-code solutions.

    Explore related topics

    FREE TRIAL Ready to get started?