Configuration of Watermarks on Product Photos in 1C-Bitrix
A competitor downloads photos from the catalog and uses them on their site. This happens precisely because images lack shop identifier. A watermark is minimal protection, but it works as a barrier against lazy copying.
Where Bitrix processes images
All images in Bitrix pass through the main module, class CFile. Resizing and conversion happen when calling CFile::ResizeImageGet() or when generating thumbnails via component. Processed files are cached physically in /upload/resize_cache/.
Watermark is not built into standard CFile. Bitrix provides the \Bitrix\Main\Diag\Image class and wrapper \Bitrix\Main\IO\File, but watermark processing is implemented in separate functionality — via main module settings in the admin panel.
Built-in mechanism: main module settings
In the admin panel (/bitrix/admin/settings.php?lang=en&mid=main) there's a "Watermarks" section. Parameters are saved in b_option with module main:
-
use_watermark_text— use text as watermark -
use_watermark_image— use image -
watermark_text— watermark text -
watermark_text_color— color in R,G,B format -
watermark_text_size— font size -
watermark_position— position (TL, TC, TR, CL, CC, CR, BL, BC, BR) -
watermark_image_path— path to watermark image file -
watermark_image_alpha— transparency (0–100)
Built-in mechanism applies watermark when calling CFile::ResizeImageGet() with parameter $bUseWatermark = true. Component bitrix:catalog.element doesn't pass this parameter by default — must explicitly set it in component parameters or template.
Programmatic watermark application via GD
For non-standard positioning or dynamic watermark content (price, date) use direct GD work:
function applyWatermark(string $sourcePath, string $outputPath): void
{
$info = getimagesize($sourcePath);
$src = match($info[2]) {
IMAGETYPE_JPEG => imagecreatefromjpeg($sourcePath),
IMAGETYPE_PNG => imagecreatefrompng($sourcePath),
IMAGETYPE_WEBP => imagecreatefromwebp($sourcePath),
default => throw new \RuntimeException('Unsupported format'),
};
$wmPath = $_SERVER['DOCUMENT_ROOT'] . '/local/watermark.png';
$wm = imagecreatefrompng($wmPath);
$srcW = imagesx($src);
$srcH = imagesy($src);
$wmW = imagesx($wm);
$wmH = imagesy($wm);
// Position: bottom-right corner with 10px margin
$destX = $srcW - $wmW - 10;
$destY = $srcH - $wmH - 10;
imagecopy($src, $wm, $destX, $destY, 0, 0, $wmW, $wmH);
match($info[2]) {
IMAGETYPE_JPEG => imagejpeg($src, $outputPath, 90),
IMAGETYPE_PNG => imagepng($src, $outputPath),
IMAGETYPE_WEBP => imagewebp($src, $outputPath, 85),
};
imagedestroy($src);
imagedestroy($wm);
}
Caching and performance
Watermark shouldn't be applied on every request. Processed image is cached in /upload/watermarked/{$fileId}/ with name including hash of watermark parameters. When logo or position changes — hash changes, cache is invalidated automatically.
For mass processing of existing images: agent or CLI-script iterates through b_file by field MODULE_ID = 'iblock' and processes files in batches of 50–100. On 10,000 images averaging 200 KB each, processing takes 15–30 minutes on normal server.
What to configure
- Built-in watermark parameters in
b_optionformainmodule - Pass
bUseWatermarkflag in catalog components - Custom watermark application function via GD for non-standard requirements
-
/upload/watermarked/cache directory with proper permissions - Agent for mass processing of existing images
- Exceptions: images of certain categories or brands without watermark







