Как делал я.
1. В .htaccess написал rewriterule, чтобы все обращения к картинкам передавались в специальный php-скрипт.
2. Скрипт проверял, есть ли в кеше картинка с водяным знаком
2.1 Если есть, то через readfile() отдавал эту картинку
2.2 Если нет, то накладываем знак и сохраняем в кеш. Выводим опять же, через readfile()
А вот и правило для .htaccess
RewriteCond %{REQUEST_URI} \.(jpeg|jpg)
RewriteCond %{HTTP_REFERER} !textpattern
RewriteRule \.(jpeg|jpg) /images/watermark/index.php [NC]
Проверяем, чтобы это была картинка jpg или jpeg…
… чтобы эта картинка не была запрошена из-под админки и…
… отправляем в скрипт запрос
В скрипте картинка доступна в $_SERVER['REQUEST_URI']