A lightweight, framework-agnostic Java library for adding watermarks to various file types, including PDFs and videos. The library was developed to address the challenge of creating watermarks that cannot be easily removed from PDF files. Many PDF editors allow users to edit even secured files, and when a watermark is added as a separate layer, it can be easily removed.
-
Internal DSL: Provides a user-friendly way to configure and apply watermarks with ease, while also ensuring type safety at compilation time.
-
Types of Watermarks:
- Text-based watermarks
- Image-based watermarks
-
Customizable Watermarks: Customize various aspects of your watermark, including:
- Font
- Color
- Size
- Position
- Rotation
- Opacity
- DPI
-
Trademarks: A capability to add the trademark symbol ® to text-based watermarks.
-
Page orientation support: Full support for both portrait and landscape orientations.
-
Supported Formats:
- Images (JPEG, PNG, etc.)
- Videos (MP4, MOV, AVI, MKV, etc)
-
Drawn Watermarks: The library provides the
WatermarkingMethod.DRAWmethod to add watermarks to PDF files that can't be easily removed. This mode generates an image from a PDF page, applies watermarks to the image, and replaces all layers of the page with the modified image. -
Multithreading: Leverages a thread pool for efficient watermarking. Particularly useful for the
WatermarkingMethod.DRAWmethod and multi-page files such as PDFs, enabling parallel watermarking with a separate thread for each page.
- Java 11 or higher
- Maven or Gradle
For Maven, add the following dependency to your pom.xml:
<dependency>
<groupId>io.github.watermark-lab</groupId>
<artifactId>WaterMarkIt</artifactId>
<version>1.4.1</version>
</dependency>For Gradle, add the following to your build.gradle:
implementation 'io.github.watermark-lab:WaterMarkIt:1.4.1'WatermarkService.create(
//use a thread pool when necessary - for instance, for large PDFs with many pages
Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors()
)
)
.watermarkPDF(new File("path/to/file.pdf"))
.withImage(new File("path/to/watermark.png"))
.position(WatermarkPosition.CENTER).end()
.opacity(20)
.and()
.withText("WaterMarkIt")
.font(Font.ARIAL)
.bold()
.color(Color.BLUE)
.addTrademark()
.end()
.position(WatermarkPosition.TILED)
.adjust(35, 0)
.horizontalSpacing(10)
.end()
.opacity(10)
.rotation(25)
.size(110)
.and()
.withText(LocalDateTime.now().toString()).end()
.position(WatermarkPosition.TOP_RIGHT)
.adjust(0, -30)
.end()
.size(50)
.apply()// skip the first page (the page index starts from 0)
WatermarkService.create()
.watermarkPDF(document)
.withText("Text-based Watermark").end()
.pageFilter(index -> index >= 1)
.apply()// don't add a watermark for the owner of the file; the owner has access to the original file.
WatermarkService.create()
.watermarkPDF(document)
.withText("Text-based Watermark").end()
.enableIf(!isOwner)
.apply()// Apply watermark only if the document has more than 3 pages
WatermarkService.create()
.watermarkPDF(document)
.withText("Text-based Watermark").end()
.documentFilter(document -> document.getNumberOfPages() > 3)
.apply() The library supports adding watermarks to video files using FFmpeg. This feature allows you to apply both text-based and image-based watermarks to various video formats.
-
FFmpeg: The library requires FFmpeg to be installed on your system and available in the system PATH. FFmpeg is used internally to process video files and apply watermarks.
Installation:
- Windows: Download from FFmpeg official website or use package managers like Chocolatey (
choco install ffmpeg) - macOS: Use Homebrew (
brew install ffmpeg) - Linux: Use your distribution's package manager (e.g.,
sudo apt install ffmpegon Ubuntu)
- Windows: Download from FFmpeg official website or use package managers like Chocolatey (
WatermarkService.create()
.watermarkVideo(videoFile)
.withText("WaterMarkIt")
.color(Color.RED)
.end()
.opacity(50)
.position(WatermarkPosition.CENTER).end()
.size(30)
.and()
.withImage(logoFile)
.position(WatermarkPosition.BOTTOM_RIGHT).end()
.size(8)
.apply();The library uses Java's ServiceLoader mechanism to load implementations of various services. You can override the services that implement the Prioritizable interface.
- Create your own implementation of the desired service interface
- Implement the
getPriority()method to return a value higher than the default implementation - Register your implementation in the
META-INF/servicesdirectory
public class CustomPdfWatermarker implements DrawPdfWatermarker {
@Override
public int getPriority() {
// Return a value higher than default to take precedence
return Prioritizable.DEFAULT_PRIORITY + 1;
}
@Override
public void watermark(PDDocument document, int pageIndex, List<WatermarkAttributes> attrs) throws IOException {
// Custom watermarking implementation
}
}Then create a file META-INF/services/com.markit.pdf.draw.DrawPdfWatermarker containing:
com.example.CustomPdfWatermarker
While WaterMarkIt is primarily a Java library targeting Java 11 for better compatibility, we selectively use Kotlin in specific areas to enhance code quality and developer experience:
- Test Code: Kotlin's concise syntax and powerful testing features make our test suite more readable and maintainable
- Data Classes: Java 11 lacks records (introduced in Java 14+), so we use Kotlin's data classes for immutable value objects
- Enums: Kotlin enums provide cleaner syntax for associating data with enum values
- Exception Classes: Custom exceptions benefit from Kotlin's concise class declarations with automatic constructor generation
When contributing to WaterMarkIt:
- Use Java for all public APIs and core library functionality
- Use Kotlin for test classes, internal data structures, and utility classes where it provides clear benefits
- Apache PDFBox: Apache PDFBox - A Java library for working with PDF documents.
- JAI Image I/O: JAI Image I/O - Image I/O library for Java, supporting various image formats.
- commons-logging: Apache Commons Logging - A simple logging facade for Java.
We welcome contributions from the community! If you'd like to contribute to WaterMarkIt, please read our Contributing Guide for details on how to get started, our coding standards, and the pull request process.
Your contributions help make WaterMarkIt better for everyone!