tomedio / pdf-watermark
A PHP library for adding text and image watermarks to PDF files using FPDI
Requires
- php: ^8.1
- setasign/fpdi-tcpdf: ^2.3
- symfony/process: ^6.0
- tecnickcom/tcpdf: ^6.6
Requires (Dev)
- phpunit/phpunit: ^10.0
- squizlabs/php_codesniffer: ^3.7
README
A PHP library for adding text and image watermarks to PDF files using FPDI.
Features
-
Add text watermarks with customizable:
- Font size, color, and opacity
- Font style (bold, italic, etc.)
- Background color and opacity
- Rotation angle (only available with center position)
- Position (top-left, center, bottom-right, etc.)
- Pages to apply the watermark to (specific pages, ranges, last page, all pages)
- Page number placeholder support (%d)
-
Add image watermarks with customizable:
- Opacity
- Rotation angle (only available with center position)
- Scaling or explicit dimensions
- Position
- Pages to apply the watermark to
- Automatic scaling to fit page boundaries
-
Works with compressed PDF files and PDFs with versions higher than 1.4
-
Recognizes page sizes and orientations
-
Modifies existing pages without adding new ones
-
Configuration-based approach
-
Configurable temporary directory for processing files
Requirements
- PHP 8.1 or higher
- pdftk (recommended for handling compressed PDFs with versions higher than 1.4)
Installation
1. Install pdftk (optional but recommended)
pdftk is used as a workaround for handling compressed PDFs with versions higher than 1.4.
On Ubuntu/Debian:
sudo apt-get update sudo apt-get install pdftk
On macOS (using Homebrew):
brew install pdftk-java
On Windows:
Download and install pdftk from the official website.
2. Install the library via Composer
composer require tomedio/pdf-watermark
Basic Usage
Adding a Text Watermark
use PdfWatermark\PdfWatermarkerFactory; use PdfWatermark\Watermark\AbstractWatermark; // Create a factory (optionally specify the path to pdftk and a custom temp directory) $factory = new PdfWatermarkerFactory('pdftk', '/path/to/custom/temp/dir'); // Create and configure a text watermark config $textConfig = $factory->createTextWatermarkConfig('CONFIDENTIAL'); $textConfig ->setPosition(AbstractWatermark::POSITION_CENTER) ->setAngle(45) ->setOpacity(0.5) ->setFontSize(72) ->setTextColor(255, 0, 0) // Red text ->setBackgroundColor(255, 255, 255) // White background ->setBackgroundOpacity(0.0) // Transparent background ->setPages('all'); // Apply to all pages // Create a watermarker with the text watermark $watermarker = $factory->createWithTextWatermark($textConfig); // Apply the watermark $watermarker->apply('input.pdf', 'output.pdf');
Adding an Image Watermark
use PdfWatermark\PdfWatermarkerFactory; use PdfWatermark\Watermark\AbstractWatermark; // Create a factory $factory = new PdfWatermarkerFactory(); // Create and configure an image watermark config $imageConfig = $factory->createImageWatermarkConfig('logo.png'); $imageConfig ->setPosition(AbstractWatermark::POSITION_BOTTOM_RIGHT) ->setOpacity(0.3) ->setAngle(0) ->setScale(0.2) // Scale to 20% of original size ->setPages('all'); // Create a watermarker with the image watermark $watermarker = $factory->createWithImageWatermark($imageConfig); // Apply the watermark $watermarker->apply('input.pdf', 'output.pdf');
Note: If the image watermark exceeds the page size, it will be automatically scaled down proportionally to fit within the page boundaries while maintaining its aspect ratio.
Adding Multiple Watermarks
use PdfWatermark\PdfWatermarkerFactory; use PdfWatermark\Watermark\AbstractWatermark; // Create a factory $factory = new PdfWatermarkerFactory(); // Create a watermarker $watermarker = $factory->create(); // Create and configure a text watermark $textConfig = $factory->createTextWatermarkConfig('CONFIDENTIAL'); $textConfig ->setPosition(AbstractWatermark::POSITION_CENTER) ->setAngle(45) ->setOpacity(0.5) ->setFontSize(72) ->setTextColor(255, 0, 0); $textWatermark = $factory->createTextWatermark($textConfig); $watermarker->addWatermark($textWatermark); // Create and configure an image watermark $imageConfig = $factory->createImageWatermarkConfig('logo.png'); $imageConfig ->setPosition(AbstractWatermark::POSITION_BOTTOM_RIGHT) ->setOpacity(0.3) ->setScale(0.2); $imageWatermark = $factory->createImageWatermark($imageConfig); $watermarker->addWatermark($imageWatermark); // Apply the watermarks $watermarker->apply('input.pdf', 'output.pdf');
Page Selection
You can specify which pages to apply the watermark to:
// Apply to all pages (default) $config->setPages('all'); // Apply to a specific page $config->setPages(1); // First page only // Apply to a range of pages $config->setPages('2-5'); // Pages 2 to 5 // Apply to a range of pages to the end $config->setPages('2-last'); // From page 2 to the last page // Apply to the last page only $config->setPages('last'); // Apply to multiple specific pages or ranges using a comma-separated string $config->setPages('1-2,4'); // Pages 1, 2, and 4 // Apply to a combination of specific pages, ranges, and special values $config->setPages('1,3-5,last'); // Pages 1, 3, 4, 5, and the last page // Apply to multiple specific pages or ranges using an array $config->setPages([1, '3-5', 'last']);
Custom Temporary Directory
You can specify a custom temporary directory for processing files:
// Specify a custom temp directory in the factory $factory = new PdfWatermarkerFactory('pdftk', '/path/to/custom/temp/dir'); // Or directly in the PdfWatermarker constructor $watermarker = new PdfWatermarker('pdftk', '/path/to/custom/temp/dir');
If no temporary directory is specified, the system's default temporary directory (sys_get_temp_dir()
) will be used.
API Documentation
PdfWatermarkerFactory
The factory class provides methods to create watermarkers, watermark configurations, and watermarks.
Methods
__construct(?string $pdftk = null, ?string $tempDir = null)
: Constructorcreate(): PdfWatermarker
: Create a new PdfWatermarker instancecreateTextWatermarkConfig(string $text): TextWatermarkConfig
: Create a new text watermark configurationcreateImageWatermarkConfig(string $imagePath): ImageWatermarkConfig
: Create a new image watermark configurationcreateTextWatermark(TextWatermarkConfig $config): TextWatermark
: Create a new text watermarkcreateImageWatermark(ImageWatermarkConfig $config): ImageWatermark
: Create a new image watermarkcreateWithTextWatermark(TextWatermarkConfig $config): PdfWatermarker
: Create a PdfWatermarker with a text watermarkcreateWithImageWatermark(ImageWatermarkConfig $config): PdfWatermarker
: Create a PdfWatermarker with an image watermark
PdfWatermarker
The main class for applying watermarks to PDF files.
Methods
__construct(?string $pdftk = null, ?string $tempDir = null)
: ConstructoraddWatermark(AbstractWatermark $watermark): self
: Add a watermark to be appliedapply(string $inputFile, string $outputFile): void
: Apply watermarks to a PDF file
AbstractWatermark
The base class for all watermarks.
Constants
POSITION_TOP_LEFT
: Position at the top-left cornerPOSITION_TOP_CENTER
: Position at the top-centerPOSITION_TOP_RIGHT
: Position at the top-right cornerPOSITION_MIDDLE_LEFT
: Position at the middle-leftPOSITION_CENTER
: Position at the centerPOSITION_MIDDLE_RIGHT
: Position at the middle-rightPOSITION_BOTTOM_LEFT
: Position at the bottom-left cornerPOSITION_BOTTOM_CENTER
: Position at the bottom-centerPOSITION_BOTTOM_RIGHT
: Position at the bottom-right corner
TextWatermarkConfig
Configuration class for text watermarks.
Constants
FONT_STYLE_REGULAR
: Regular font style (no formatting)FONT_STYLE_BOLD
: Bold font styleFONT_STYLE_ITALIC
: Italic font styleFONT_STYLE_UNDERLINE
: Underlined font styleFONT_STYLE_STRIKETHROUGH
: Strikethrough font style
Methods
__construct(string $text)
: ConstructorsetPosition(string $position): self
: Set the position of the watermarksetOpacity(float $opacity): self
: Set the opacity of the watermark (0.0 to 1.0)setAngle(float $angle): self
: Set the rotation angle of the watermark in degrees (only works with center position)setPages(array|string $pages): self
: Set pages to apply the watermark tosetFontSize(int $fontSize): self
: Set the font size in pointssetTextColor(int $r, int $g, int $b): self
: Set the text color in RGB format (0-255)setTextOpacity(float $opacity): self
: Set the text opacity (0.0 to 1.0)setBackgroundColor(int $r, int $g, int $b): self
: Set the background color in RGB format (0-255)setBackgroundOpacity(float $opacity): self
: Set the background opacity (0.0 to 1.0)setFontName(string $fontName): self
: Set the font namesetFontStyle(int $fontStyle): self
: Set the font style using constants (e.g.,TextWatermarkConfig::FONT_STYLE_BOLD
,TextWatermarkConfig::FONT_STYLE_ITALIC
)
ImageWatermarkConfig
Configuration class for image watermarks.
Methods
__construct(string $imagePath)
: ConstructorsetPosition(string $position): self
: Set the position of the watermarksetOpacity(float $opacity): self
: Set the opacity of the watermark (0.0 to 1.0)setAngle(float $angle): self
: Set the rotation angle of the watermark in degrees (only works with center position)setPages(array|string $pages): self
: Set pages to apply the watermark tosetScale(float $scale): self
: Set the scale of the image (1.0 = original size). If the scaled image exceeds the page size, it will be automatically scaled down proportionally to fit within the page boundaries.setWidth(int $width): self
: Set the width of the image (height will be calculated to maintain aspect ratio). If the resulting image exceeds the page size, it will be automatically scaled down proportionally to fit within the page boundaries.setHeight(int $height): self
: Set the height of the image (width will be calculated to maintain aspect ratio). If the resulting image exceeds the page size, it will be automatically scaled down proportionally to fit within the page boundaries.
PDF Version Compatibility
This library uses FPDI to process PDF files, which has a limitation with compressed PDFs that have versions higher than 1.4. To overcome this limitation, the library implements a workaround using pdftk:
- When a PDF cannot be processed directly with FPDI (typically due to being a compressed PDF with version > 1.4), the library automatically falls back to using pdftk.
- pdftk is used to uncompress the PDF, making it compatible with FPDI.
- The watermarks are applied to the uncompressed PDF using FPDI.
- The resulting PDF is recompressed using pdftk.
This approach allows the library to work with a wide range of PDF files, including those with higher versions, without requiring the paid version of FPDI.
Advanced Usage
Using Page Number Placeholder
You can include the page number in your text watermark using the %d
placeholder:
// Create a text watermark with page number $textConfig = $factory->createTextWatermarkConfig('Page %d'); $textConfig ->setPosition(AbstractWatermark::POSITION_BOTTOM_CENTER) ->setOpacity(0.5) ->setFontSize(10) ->setTextColor(0, 0, 0); $watermarker = $factory->createWithTextWatermark($textConfig); $watermarker->apply('input.pdf', 'output.pdf');
Setting Font Name and Style
Font Name
You can set the font name for text watermarks using predefined constants or custom font names:
use PdfWatermark\Watermark\Config\TextWatermarkConfig; $textConfig = $factory->createTextWatermarkConfig('CONFIDENTIAL'); // Using predefined font constants $textConfig->setFontName(TextWatermarkConfig::FONT_HELVETICA); $textConfig->setFontName(TextWatermarkConfig::FONT_COURIER); $textConfig->setFontName(TextWatermarkConfig::FONT_TIMES); $textConfig->setFontName(TextWatermarkConfig::FONT_SYMBOL); // Or using a string directly $textConfig->setFontName('Helvetica'); // You can also use custom fonts if they are available in your TCPDF installation $textConfig->setFontName('YourCustomFont');
Font Style
You can set the font style for text watermarks using constants:
$textConfig ->setFontName(TextWatermarkConfig::FONT_HELVETICA) ->setFontStyle(TextWatermarkConfig::FONT_STYLE_BOLD) // Use constants for font styles ->setFontSize(24);
You can also combine multiple font styles using the bitwise OR operator:
// Apply both bold and italic styles $textConfig->setFontStyle( TextWatermarkConfig::FONT_STYLE_BOLD | TextWatermarkConfig::FONT_STYLE_ITALIC ); // Apply bold, underline, and strikethrough $textConfig->setFontStyle( TextWatermarkConfig::FONT_STYLE_BOLD | TextWatermarkConfig::FONT_STYLE_UNDERLINE | TextWatermarkConfig::FONT_STYLE_STRIKETHROUGH );
Setting Explicit Dimensions for Image Watermarks
Instead of scaling, you can set explicit dimensions for image watermarks:
$imageConfig = $factory->createImageWatermarkConfig('logo.png'); $imageConfig ->setPosition(AbstractWatermark::POSITION_BOTTOM_RIGHT) ->setWidth(200); // Set width to 200 points, height will be calculated automatically // Or set height instead $imageConfig ->setHeight(100); // Set height to 100 points, width will be calculated automatically
Note: If the resulting image dimensions exceed the page size, the image will be automatically scaled down proportionally to fit within the page boundaries while maintaining its aspect ratio.
Development
Available Makefile Commands
The library includes a Makefile with several useful commands:
# Install dependencies make install # Run tests make test # Check coding standards make cs # Fix coding standards make cs-fix # Run example make example
License
This library is licensed under the MIT License.