From bb68d366417fdffb7b8647a4a76bc654731408ba Mon Sep 17 00:00:00 2001 From: Alexander Andreev Date: Sat, 21 Feb 2026 14:07:29 +0300 Subject: [PATCH] Admin/Public: add simple watermark settings Add watermark controls in admin settings for text, brightness, and angle while keeping the UI lightweight. Apply these settings to public watermark rendering for after-photos with safe value clamping across Imagick and GD output paths. --- admin.php | 42 +++++++++++++++++++++++++++++++----------- index.php | 21 ++++++++++++++++----- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/admin.php b/admin.php index a6c80f9..bd278a0 100644 --- a/admin.php +++ b/admin.php @@ -140,9 +140,22 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $message = 'Раздел удалён'; } - if ($action === 'update_welcome') { + if ($action === 'update_settings' || $action === 'update_welcome') { $text = trim((string)($_POST['welcome_text'] ?? '')); + $wmText = trim((string)($_POST['watermark_text'] ?? 'photo.andr33v.ru')); + $wmBrightness = (int)($_POST['watermark_brightness'] ?? 35); + $wmAngle = (int)($_POST['watermark_angle'] ?? -28); + + if ($wmText === '') { + $wmText = 'photo.andr33v.ru'; + } + $wmBrightness = max(5, min(100, $wmBrightness)); + $wmAngle = max(-75, min(75, $wmAngle)); + settingSet('welcome_text', $text); + settingSet('watermark_text', $wmText); + settingSet('watermark_brightness', (string)$wmBrightness); + settingSet('watermark_angle', (string)$wmAngle); $message = 'Настройки сохранены'; } @@ -379,6 +392,9 @@ if (!$activeSection && $sections !== []) { $photos = $activeSectionId > 0 ? photosBySection($activeSectionId) : []; $commenters = commentersAll(); $welcomeText = settingGet('welcome_text', 'Добро пожаловать в галерею. Выберите раздел слева, чтобы посмотреть фотографии.'); +$watermarkText = settingGet('watermark_text', 'photo.andr33v.ru'); +$watermarkBrightness = max(5, min(100, (int)settingGet('watermark_brightness', '35'))); +$watermarkAngle = max(-75, min(75, (int)settingGet('watermark_angle', '-28'))); $adminMode = (string)($_GET['mode'] ?? 'photos'); if ($adminMode === 'media') { $adminMode = 'photos'; @@ -851,8 +867,19 @@ function nextUniqueCodeName(string $base): string

Настройки

- +

+
+

Водяной знак (фото "после")

+

+

+ + +

+

+ + +

@@ -1043,16 +1070,13 @@ function nextUniqueCodeName(string $base): string

-

+

-
Тематики
- - Не выбрано - + @@ -1486,10 +1510,6 @@ function nextUniqueCodeName(string $base): string list.textContent = ''; if (!Array.isArray(topics) || topics.length === 0) { - const empty = document.createElement('span'); - empty.className = 'topic-empty js-topic-empty'; - empty.textContent = 'Не выбрано'; - list.appendChild(empty); return; } diff --git a/index.php b/index.php index d1365dd..f39b79d 100644 --- a/index.php +++ b/index.php @@ -317,14 +317,23 @@ function serveThumb(): never function outputWatermarked(string $path, string $mime): never { - $text = 'photo.andr33v.ru'; + $text = trim(settingGet('watermark_text', 'photo.andr33v.ru')); + if ($text === '') { + $text = 'photo.andr33v.ru'; + } + + $brightness = max(5, min(100, (int)settingGet('watermark_brightness', '35'))); + $angle = max(-75, min(75, (int)settingGet('watermark_angle', '-28'))); + $imagickOpacity = 0.04 + ($brightness / 100) * 0.24; + $gdAlpha = (int)round(127 - ($brightness * 0.9)); + $gdAlpha = max(10, min(126, $gdAlpha)); if (extension_loaded('imagick')) { $im = new Imagick($path); $w = max(1, (int)$im->getImageWidth()); $h = max(1, (int)$im->getImageHeight()); $draw = new ImagickDraw(); - $draw->setFillColor(new ImagickPixel('rgba(255,255,255,0.16)')); + $draw->setFillColor(new ImagickPixel('rgba(255,255,255,' . number_format($imagickOpacity, 3, '.', '') . ')')); $draw->setFontSize(max(12, (int)($w / 46))); $draw->setTextAntialias(true); @@ -333,7 +342,7 @@ function outputWatermarked(string $path, string $mime): never $stepX = max(120, (int)($w / 3)); for ($y = -$h; $y < $h * 2; $y += $stepY) { for ($x = -$w; $x < $w * 2; $x += $stepX) { - $im->annotateImage($draw, $x, $y, -28, $lineText); + $im->annotateImage($draw, $x, $y, $angle, $lineText); } } @@ -359,13 +368,15 @@ function outputWatermarked(string $path, string $mime): never } $font = 2; - $color = imagecolorallocatealpha($img, 255, 255, 255, 96); + $color = imagecolorallocatealpha($img, 255, 255, 255, $gdAlpha); $lineText = $text . ' ' . $text . ' ' . $text; $stepY = max(16, imagefontheight($font) + 8); $stepX = max(120, (int)($w / 3)); $row = 0; + $skew = max(6, min(48, (int)round(abs($angle)))); + $dir = $angle < 0 ? 1 : -1; for ($y = -$h; $y < $h * 2; $y += $stepY) { - $offset = ($row * 22) % $stepX; + $offset = ($row * $skew * $dir) % $stepX; for ($x = -$w - $offset; $x < $w * 2; $x += $stepX) { imagestring($img, $font, $x, $y, $lineText, $color); }