From 947b509f0b7f230ca7ca280bc99cf1c7276a12ca Mon Sep 17 00:00:00 2001 From: hbrain Date: Thu, 4 Jun 2026 10:39:04 +0200 Subject: [PATCH] OG image creation improved --- new.php | 91 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 23 deletions(-) diff --git a/new.php b/new.php index 41ce08f..4f72bf2 100644 --- a/new.php +++ b/new.php @@ -49,7 +49,8 @@ function slugify($s){ $s = ascii_safe($s); $s = strtolower(trim($s)); $s = preg_ function rrmdir($dir){ if(!is_dir($dir)) return; foreach(scandir($dir) as $f){ if($f==='.'||$f==='..') continue; $p="$dir/$f"; is_dir($p)?rrmdir($p):unlink($p);} rmdir($dir); } function apply_thumbnail_overlay($imagePath, $title, $teaser) { $logFile = __DIR__ . '/logs/image_magick.log'; - file_put_contents($logFile, "--- New Thumbnail Job ---\n", FILE_APPEND); + file_put_contents($logFile, "--- New Thumbnail Job --- +", FILE_APPEND); $fontPath = __DIR__ . '/assets/fonts/IBMPlexSans-SemiBold.ttf'; $titleFontPath = is_file(__DIR__ . '/assets/fonts/BebasNeue-Regular.ttf') @@ -62,8 +63,13 @@ function apply_thumbnail_overlay($imagePath, $title, $teaser) { throw new RuntimeException('Thumbnail font file is missing.'); } - $imgW = 1200; - $imgH = 630; + $scale = 3; + $baseW = 1200; + $baseH = 630; + $imgW = $baseW * $scale; + $imgH = $baseH * $scale; + $targetW = $baseW; + $targetH = $baseH; $normalize = static function ($text): string { $text = trim((string)$text); @@ -73,7 +79,8 @@ function apply_thumbnail_overlay($imagePath, $title, $teaser) { }; $wrapText = static function ($text, int $width) use ($normalize): string { $text = $normalize($text); - return $text === '' ? '' : wordwrap($text, $width, "\n", false); + return $text === '' ? '' : wordwrap($text, $width, " +", false); }; $clampWrappedText = static function ($text, int $width, int $maxLines, bool $cutLongWords = false) use ($normalize): string { $text = $normalize($text); @@ -82,8 +89,10 @@ function apply_thumbnail_overlay($imagePath, $title, $teaser) { if (!$words) return ''; $candidate = implode(' ', $words); while (true) { - $wrapped = wordwrap($candidate, $width, "\n", $cutLongWords); - $lineCount = substr_count($wrapped, "\n") + 1; + $wrapped = wordwrap($candidate, $width, " +", $cutLongWords); + $lineCount = substr_count($wrapped, " +") + 1; if ($lineCount <= $maxLines || count($words) <= 1) return $wrapped; array_pop($words); $candidate = implode(' ', $words) . '…'; @@ -97,7 +106,8 @@ function apply_thumbnail_overlay($imagePath, $title, $teaser) { for ($size = 84; $size >= 54; $size -= 4) { $width = max(16, min(46, (int)round(23 + (84 - $size) / 2.7))); $candidate = $wrapText($text, $width); - $lines = substr_count($candidate, "\n") + 1; + $lines = substr_count($candidate, " +") + 1; $bestText = $candidate; $bestSize = $size; $bestWidth = $width; @@ -107,15 +117,28 @@ function apply_thumbnail_overlay($imagePath, $title, $teaser) { return [$bestText, $bestSize, $bestWidth, $bestLines]; }; - [$titleText, $titleFontSize, $titleWrapWidth, $titleLines] = $fitTitleText($title); + [$titleText, $titleFontSizeBase, $titleWrapWidth, $titleLines] = $fitTitleText($title); $teaserText = $clampWrappedText($teaser, 34, 6, true); - $teaserLines = max(1, substr_count($teaserText, "\n") + 1); + $teaserLines = max(1, substr_count($teaserText, " +") + 1); - // Move the whole block a bit left and higher while keeping left-aligned text. - $left = max(14, (int)round($imgW * 0.046)); - $titleY = max(20, (int)round($imgH * 0.062)); - $titleLineStep = max(68, (int)round($imgH * 0.043)); - $teaserY = max((int)round($imgH * 0.235), $titleY + ($titleLines * $titleLineStep) + max(54, (int)round($imgH * 0.03))); + $baseLeft = max(14, (int)round($baseW * 0.046)); + $baseTitleY = max(20, (int)round($baseH * 0.062)); + $baseTitleLineStep = max(68, (int)round($baseH * 0.043)); + $baseTeaserY = max((int)round($baseH * 0.235), $baseTitleY + ($titleLines * $baseTitleLineStep) + max(54, (int)round($baseH * 0.03))); + + $left = $baseLeft * $scale; + $titleY = $baseTitleY * $scale; + $titleLineStep = $baseTitleLineStep * $scale; + $teaserY = $baseTeaserY * $scale; + $shadowOffset = 3 * $scale; + $titleLineSpacing = 2 * $scale; + $teaserLineSpacing = -18 * $scale; + $titlePointSize = $titleFontSizeBase * $scale; + $teaserPointSize = 58 * $scale; + $shadowFill = 'rgba(0,0,0,0.35)'; + $titleFill = '#F3F4F6'; + $teaserFill = '#EADFC9'; $overlayBase = tempnam(sys_get_temp_dir(), 'thumb_overlay_'); $outputPath = dirname($imagePath) . '/' . basename($imagePath) . '.tmp.' . uniqid('', true) . '.jpg'; @@ -126,23 +149,38 @@ function apply_thumbnail_overlay($imagePath, $title, $teaser) { @unlink($overlayBase); $cmd1 = sprintf( - '/usr/bin/convert -size %dx%d xc:none -font %s -pointsize %d -fill "#F3F4F6" -stroke black -strokewidth 2 -interline-spacing 2 -gravity northwest -annotate +%d+%d %s -font %s -pointsize 58 -fill "#EADFC9" -stroke black -strokewidth 2 -interline-spacing -18 -gravity northwest -annotate +%d+%d %s %s 2>&1', + '/usr/bin/convert -size %dx%d xc:none -font %s -pointsize %d -fill %s -interline-spacing %d -gravity northwest -annotate +%d+%d %s -fill %s -annotate +%d+%d %s -font %s -pointsize %d -fill %s -interline-spacing %d -gravity northwest -annotate +%d+%d %s -fill %s -annotate +%d+%d %s %s 2>&1', $imgW, $imgH, escapeshellarg($titleFontPath), - $titleFontSize, + $titlePointSize, + escapeshellarg($shadowFill), + $titleLineSpacing, + $left + $shadowOffset, + $titleY + $shadowOffset, + escapeshellarg($titleText), + escapeshellarg($titleFill), $left, $titleY, escapeshellarg($titleText), escapeshellarg($teaserFontPath), + $teaserPointSize, + escapeshellarg($shadowFill), + $teaserLineSpacing, + $left + $shadowOffset, + $teaserY + $shadowOffset, + escapeshellarg($teaserText), + escapeshellarg($teaserFill), $left, $teaserY, escapeshellarg($teaserText), escapeshellarg($overlayPath) ); - file_put_contents($logFile, "Overlay CMD: " . $cmd1 . "\n", FILE_APPEND); + file_put_contents($logFile, "Overlay CMD: " . $cmd1 . " +", FILE_APPEND); $out1 = shell_exec($cmd1); - file_put_contents($logFile, "Overlay Output: " . $out1 . "\n", FILE_APPEND); + file_put_contents($logFile, "Overlay Output: " . $out1 . " +", FILE_APPEND); if (!is_file($overlayPath) || filesize($overlayPath) < 100) { @unlink($overlayPath); @unlink($outputPath); @@ -150,7 +188,7 @@ function apply_thumbnail_overlay($imagePath, $title, $teaser) { } $maxBytes = 600 * 1024; - $qualities = [88, 84, 80, 76, 72, 68, 64, 60, 56, 52, 48]; + $qualities = [96, 92, 88, 84, 80, 76, 72, 68, 64]; $finalPath = ''; $finalSize = 0; $finalOut = ''; @@ -158,19 +196,25 @@ function apply_thumbnail_overlay($imagePath, $title, $teaser) { foreach ($qualities as $quality) { $attemptPath = dirname($imagePath) . '/' . basename($imagePath) . '.tmp.' . uniqid('', true) . '.jpg'; $cmd2 = sprintf( - '/usr/bin/convert -filter Lanczos -define filter:blur=0.85 %s -resize %dx%d^ -gravity center -extent %dx%d -modulate 70,82 %s -composite -strip -interlace Plane -sampling-factor 4:2:0 -quality %d %s 2>&1', + '/usr/bin/convert -filter Lanczos -define filter:blur=0.85 %s -resize %dx%d^ -gravity center -extent %dx%d -modulate 70,82 %s -composite -resize %dx%d -gravity center -extent %dx%d -unsharp 0x0.75+0.75+0.008 -strip -interlace Plane -sampling-factor 4:2:0 -quality %d %s 2>&1', escapeshellarg($imagePath), $imgW, $imgH, $imgW, $imgH, escapeshellarg($overlayPath), + $targetW, + $targetH, + $targetW, + $targetH, $quality, escapeshellarg($attemptPath) ); - file_put_contents($logFile, "Composite CMD (q=$quality): " . $cmd2 . "\n", FILE_APPEND); + file_put_contents($logFile, "Composite CMD (q=$quality): " . $cmd2 . " +", FILE_APPEND); $out2 = shell_exec($cmd2); - file_put_contents($logFile, "Composite Output (q=$quality): " . $out2 . "\n", FILE_APPEND); + file_put_contents($logFile, "Composite Output (q=$quality): " . $out2 . " +", FILE_APPEND); if (!is_file($attemptPath) || filesize($attemptPath) < 100) { @unlink($attemptPath); @@ -191,7 +235,8 @@ function apply_thumbnail_overlay($imagePath, $title, $teaser) { } if ($finalSize > $maxBytes) { - file_put_contents($logFile, "Thumbnail still above size limit: " . $finalSize . " bytes\n", FILE_APPEND); + file_put_contents($logFile, "Thumbnail still above size limit: " . $finalSize . " bytes +", FILE_APPEND); } if (!@rename($finalPath, $imagePath)) {