Watermark Above PDF Text? Or Below?

Cartoon graphic of what appears to be many different layers of glassine circles in different colors affecting how one another appear.

It’s rare for users to reach out with concerns about stampers placing watermarks over PDF text, but recently there was another inquiry about this—bringing the total to three—and the frustration expressed was evident. Maybe since all the other plugins default to placing stamps over existing text and images, people assume that’s what is possible. Or maybe people are being told it’s impossible to stamp PDFs below existing text and images. That’s not true. (If you want the TL;DR, skip to the small text at the very end of this article.)

To assist those desiring to literally “flip the script,” here are some helpful tips on managing PDF watermark layering, positioning, transparency, and legibility, ranging from pretty easy and very cheap to somewhat expensive to… a bit difficult.

1. Transparent PNG images

One user raised a concern about placing a logo (white, with a transparent background) over PDF text. Naturally, the white areas of the logo obstructed the text beneath it, which can be problematic.

Fortunately, a solution is simple: by editing the PNG file in an image editing program (such as Photoshop or Affinity Photo), the logo can be darkened to a more suitable color, such as black, and the opacity can be reduced to around 10%. The logo should also maintain a transparent background to ensure it doesn’t completely obscure the text.

With this adjustment, the watermark will overlay the text without making it hard to read. In fact, the transparency of the watermark may even improve text visibility, depending on the opacity.

2. Upgrade to SetaPDF-Stamper

While it’s never ideal to suggest additional purchases, investing in the right tools can significantly improve workflow. SetaSign offers the best PDF-parsing libraries out there, and they are highly regarded for both the quality of their product and their customer support. In partnership with SetaSign, PDF Ink users receive a 20% discount on their product.

By installing SetaPDF-Stamper alongside PDF Ink, users can easily switch watermarks to be placed behind PDF content with a single line of code. This quick change can help ensure watermark placement works seamlessly with the rest of the PDF content. The code to achieve this is:

add_filter( 'pdfink_filter_setapdf_stamper_addstamp_underlay', '__return_true' );

Add that one line of PHP code to your child theme functions.php file or by using the “Code Snippets” WP plugin, and you are done.

Easy, right?

3. Add a Child Class to PDF Ink

“Toto, I’ve a feeling we’re not in Kansas anymore”

We understand that many users may feel overwhelmed by longer PHP code, and we certainly don’t want to add to that. However, we wanted to let you know that the PDF handlers in PDF Ink are fully extensible with PHP, offering the flexibility to tailor the functionality to your specific needs.

New Custom PDF Handler

Take a look at the code. The handler for TCPDF (tcpdf.php) is in the PDF Ink plugin /src/pdf/strategy/ folder. Make a copy of that tcpdf.php file that you can edit, maybe name it “custom_tcpdf.php“.

Inside the loop of PDF pages, the setup_page() method is called.

for ( $i = 1; $i <= $this->page_count; $i++ ) {

Since that method is called early in the loop, the PDF page is re-created before the watermark is added. Using knowledge of how TCPDI and TCPDF work, we need to split up the setup_page() method and put the part that parses the page before the watermarking, and the part that re-writes the existing PDF data after the watermarking.

To start, remove the line which comes shortly after the “loop” line just mentioned, above

$this->setup_page( $i, $margin_top_bottom );

And replace it with something like this:

if ( is_a( $this->handler, 'setasign\Fpdi\Tcpdf\Fpdi' ) ) {
  $idx = $this->handler->importPage( $i, '/BleedBox', true, true );
  $handler = 'fpdi-tcpdf';
} else {
  $idx = $this->handler->importPage( $i, '/BleedBox' );
  $this->handler->importAnnotations( $i );
  $handler = 'tcpdi-tcpdf';
}
$this->size = $this->handler->getTemplateSize( $idx );
$this->size['width'] = $this->size['w'] ?? $this->size['width'];
$this->size['height'] = $this->size['h'] ?? $this->size['height'];
$orientation = ( $this->size['width'] > $this->size['height'] ) ? 'L' : 'P';
$size_array = [ $this->size['width'], $this->size['height'] ];
if ( ! empty( $margin_top_bottom ) ) {
  $this->handler->SetAutoPageBreak( true, $margin_top_bottom );
}
$this->handler->AddPage( $orientation, '', false, false, $this->metadata );
if ( 'tcpdi-tcpdf' === $handler ) {
  $this->handler->setPageFormatFromTemplatePage( $i, $orientation, $size_array );
}

Then, after the line:

$this->maybe_add_barcode( $this->handler, $settings );

Add this:

$this->handler->useTemplate( $idx );

Your Custom Plugin

Follow along step-by-step and you will build your first WordPress plugin. Don’t want to do this yourself? Write to us and we will sell you the add-on for $29. (Why isn’t it core? Because we’ve literally ever had it requested three times in over ten years. More on that at the very end of this post.)

So now you have a customized version of class pdfInk_PDF_Strategy_TCPDF. Rename the class by replacing the line:

<?php

namespace LittlePackage\pdfInk\PDF\Strategy;

use Exception;

/**
 * Class pdfInk_PDF_Strategy_TCPDF
 * Handles TCPDF manipulations using mixed parsers. (Expects FPDI or TCPDI)
 */
class pdfInk_PDF_Strategy_TCPDF extends pdfInk_PDF_Strategy_Base {

with:

<?php

namespace LittlePackage\pdfInkUnderneath\PDF\Strategy;
use LittlePackage\pdfInk\PDF\Strategy\pdfInk_PDF_Strategy_Base;
use Exception;

/**
 * Class pdfInk_PDF_Strategy_TCPDF
 * Handles TCPDF manipulations using mixed parsers. (Expects FPDI or TCPDI)
 */
class custom_PDF_Strategy_TCPDF extends pdfInk_PDF_Strategy_Base {

We aren’t replacing the original PDF Ink tcpdf.php file. Leave that original plugin file where it is, and leave it alone. We used it for its guts (we copy and pasted them to custom-tcpdf.php) and now are done with it.

We are adding custom-tcpdf.php as another file to run in our new little plugin. Our plugin will have two files inside a folder.

pdf-ink-underneath/
├── pdf-ink-underneath.php
└── custom-tcpdf.php

Create a file called “pdf-ink-underneath.php” and put this content in it:

<?php
/*
 * Plugin Name: PDF Ink Underneath
 * Plugin URI: https://pdfink.com
 * Description: Custom add-on for PDF Ink to allow watermark to be underneath PDF content
 * Version: 1.0.0
 * Author: Little Package
 * Requires PHP: 7.2
 * WC requires at least: 4.0
 * WC tested up to: 9.6
 *
 * Text Domain: pdf-ink
 * Domain path: /lang
 *
 * Copyright 2025 Little Package
 * License: GNU General Public License v3.0
 * License URI: http://www.gnu.org/licenses/gpl-3.0.html
 *
 * This file is part of PDF Ink Underneath, a plugin for WordPress.
 *
 * PDF Ink Underneath is distributed in the hope that it will
 * be useful, but WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with WordPress.
 * If not, see <http://www.gnu.org/licenses/gpl-3.0.html>.
 *
 */
defined( 'ABSPATH' ) || exit;

function pdfink_underneath_plugins_loaded() {
	include WP_PLUGIN_DIR . '/pdf-ink/src/pdf/strategy/interface.php';
	include WP_PLUGIN_DIR . '/pdf-ink/src/pdf/strategy/base.php';
	include 'custom-tcpdf.php';
}
add_action( 'plugins_loaded', 'pdfink_underneath_plugins_loaded', 1 );

add_filter( 'pdfink_strategy_for_library', function( $strategy, $library, $lib ) {
	if ( 'tcpdi-tcpdf' === $library ) {
		// Return your custom strategy class in 'custom-tcpdf.php';
		return new \LittlePackage\pdfInkUnderneath\PDF\Strategy\custom_PDF_Strategy_TCPDF( $lib );
	}
	return $strategy;
}, 10, 3 );

Save the file in the same folder as the custom_tcpdf.php file. Re-name the folder “pdf-ink-underneath“. You now officially have a WordPress plugin. This plugin is compatible with PDF Ink version 1.0.4 and above.

Upload the folder to your wp-content/plugins folder and activate it in your WordPress Plugins screen.

“You’ve always had the power, my dear. You’ve had it all along”


Have you built or purchased an add-on that isn’t quite working as expected? Here’s an important reason we don’t include this functionality in the core product. Many PDFs contain background layers (often white or light-colored) behind the text and images. If we were to place PDF Ink watermarks underneath the PDF content, it could end up hidden behind those background layers, making it invisible. There’s no way to guarantee where our stamp would end up in a PDF’s multiple layers, so the result would often be that the watermark wouldn’t show at all. That would be so much bummer town, all the time.

For that reason, we position our stamp on top of the content, ensuring visibility. If you’re certain that none of your PDFs contain background layers that would obscure the watermark, or you WANT to totally obscure the watermark in a tricky way, feel free to give this script a try. We’re here to help make sure it works for you!

To top