Use article IDs for permalinks and OG images
This commit is contained in:
parent
fbc4f1045a
commit
37e43b6bca
3 changed files with 168 additions and 59 deletions
130
new.php
130
new.php
|
|
@ -62,9 +62,8 @@ function apply_thumbnail_overlay($imagePath, $title, $teaser) {
|
|||
throw new RuntimeException('Thumbnail font file is missing.');
|
||||
}
|
||||
|
||||
$dims = @getimagesize($imagePath);
|
||||
$imgW = max(1, (int)($dims[0] ?? 1920));
|
||||
$imgH = max(1, (int)($dims[1] ?? 1080));
|
||||
$imgW = 1200;
|
||||
$imgH = 630;
|
||||
|
||||
$normalize = static function ($text): string {
|
||||
$text = trim((string)$text);
|
||||
|
|
@ -92,11 +91,11 @@ function apply_thumbnail_overlay($imagePath, $title, $teaser) {
|
|||
};
|
||||
$fitTitleText = static function ($text) use ($wrapText): array {
|
||||
$bestText = '';
|
||||
$bestSize = 285;
|
||||
$bestWidth = 18;
|
||||
$bestSize = 95;
|
||||
$bestWidth = 28;
|
||||
$bestLines = 1;
|
||||
for ($size = 320; $size >= 240; $size -= 5) {
|
||||
$width = max(14, min(28, (int)round(22 + (285 - $size) / 8)));
|
||||
for ($size = 94; $size >= 60; $size -= 4) {
|
||||
$width = max(16, min(46, (int)round(24 + (94 - $size) / 2.7)));
|
||||
$candidate = $wrapText($text, $width);
|
||||
$lines = substr_count($candidate, "\n") + 1;
|
||||
$bestText = $candidate;
|
||||
|
|
@ -109,14 +108,14 @@ function apply_thumbnail_overlay($imagePath, $title, $teaser) {
|
|||
};
|
||||
|
||||
[$titleText, $titleFontSize, $titleWrapWidth, $titleLines] = $fitTitleText($title);
|
||||
$teaserText = $clampWrappedText($teaser, 34, 5);
|
||||
$teaserText = $clampWrappedText($teaser, 38, 6);
|
||||
$teaserLines = max(1, substr_count($teaserText, "\n") + 1);
|
||||
|
||||
// Move the whole block a bit right while keeping left-aligned text.
|
||||
$left = max(18, (int)round($imgW * 0.055));
|
||||
$titleY = max(24, (int)round($imgH * 0.06));
|
||||
$titleLineStep = max(230, (int)round($imgH * 0.085));
|
||||
$teaserY = max((int)round($imgH * 0.27), $titleY + ($titleLines * $titleLineStep) + max(140, (int)round($imgH * 0.06)));
|
||||
$titleLineStep = max(68, (int)round($imgH * 0.043));
|
||||
$teaserY = max((int)round($imgH * 0.25), $titleY + ($titleLines * $titleLineStep) + max(56, (int)round($imgH * 0.03)));
|
||||
|
||||
$overlayBase = tempnam(sys_get_temp_dir(), 'thumb_overlay_');
|
||||
$outputPath = dirname($imagePath) . '/' . basename($imagePath) . '.tmp.' . uniqid('', true) . '.jpg';
|
||||
|
|
@ -127,7 +126,7 @@ 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 7 -interline-spacing 2 -gravity northwest -annotate +%d+%d %s -font %s -pointsize 220 -fill "#EADFC9" -stroke black -strokewidth 6 -interline-spacing -90 -gravity northwest -annotate +%d+%d %s %s 2>&1',
|
||||
'/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',
|
||||
$imgW,
|
||||
$imgH,
|
||||
escapeshellarg($titleFontPath),
|
||||
|
|
@ -150,25 +149,54 @@ function apply_thumbnail_overlay($imagePath, $title, $teaser) {
|
|||
throw new RuntimeException('Failed to render thumbnail overlay: ' . trim((string)$out1));
|
||||
}
|
||||
|
||||
$cmd2 = sprintf(
|
||||
'/usr/bin/convert %s -modulate 56,78 %s -composite %s 2>&1',
|
||||
escapeshellarg($imagePath),
|
||||
escapeshellarg($overlayPath),
|
||||
escapeshellarg($outputPath)
|
||||
);
|
||||
file_put_contents($logFile, "Composite CMD: " . $cmd2 . "\n", FILE_APPEND);
|
||||
$out2 = shell_exec($cmd2);
|
||||
file_put_contents($logFile, "Composite Output: " . $out2 . "\n", FILE_APPEND);
|
||||
$maxBytes = 600 * 1024;
|
||||
$qualities = [88, 84, 80, 76, 72, 68, 64, 60, 56, 52, 48];
|
||||
$finalPath = '';
|
||||
$finalSize = 0;
|
||||
$finalOut = '';
|
||||
|
||||
if (!is_file($outputPath) || filesize($outputPath) < 100) {
|
||||
@unlink($overlayPath);
|
||||
@unlink($outputPath);
|
||||
throw new RuntimeException('Failed to compose thumbnail overlay: ' . trim((string)$out2));
|
||||
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 62,76 %s -composite -strip -interlace Plane -sampling-factor 4:2:0 -quality %d %s 2>&1',
|
||||
escapeshellarg($imagePath),
|
||||
$imgW,
|
||||
$imgH,
|
||||
$imgW,
|
||||
$imgH,
|
||||
escapeshellarg($overlayPath),
|
||||
$quality,
|
||||
escapeshellarg($attemptPath)
|
||||
);
|
||||
file_put_contents($logFile, "Composite CMD (q=$quality): " . $cmd2 . "\n", FILE_APPEND);
|
||||
$out2 = shell_exec($cmd2);
|
||||
file_put_contents($logFile, "Composite Output (q=$quality): " . $out2 . "\n", FILE_APPEND);
|
||||
|
||||
if (!is_file($attemptPath) || filesize($attemptPath) < 100) {
|
||||
@unlink($attemptPath);
|
||||
$finalOut = trim((string)$out2);
|
||||
continue;
|
||||
}
|
||||
|
||||
$finalPath = $attemptPath;
|
||||
$finalSize = filesize($attemptPath);
|
||||
$finalOut = trim((string)$out2);
|
||||
if ($finalSize <= $maxBytes) break;
|
||||
}
|
||||
|
||||
if (!@rename($outputPath, $imagePath)) {
|
||||
if ($finalPath === '') {
|
||||
@unlink($overlayPath);
|
||||
@unlink($outputPath);
|
||||
throw new RuntimeException('Failed to compose thumbnail overlay: ' . $finalOut);
|
||||
}
|
||||
|
||||
if ($finalSize > $maxBytes) {
|
||||
file_put_contents($logFile, "Thumbnail still above size limit: " . $finalSize . " bytes\n", FILE_APPEND);
|
||||
}
|
||||
|
||||
if (!@rename($finalPath, $imagePath)) {
|
||||
@unlink($overlayPath);
|
||||
@unlink($finalPath);
|
||||
throw new RuntimeException('Failed to replace thumbnail image.');
|
||||
}
|
||||
|
||||
|
|
@ -700,13 +728,27 @@ function is_image_media_file($name){
|
|||
$ext = strtolower(pathinfo((string)$name, PATHINFO_EXTENSION));
|
||||
return in_array($ext, ['jpg','jpeg','png','webp','gif'], true);
|
||||
}
|
||||
function public_url_path($path){
|
||||
$path = str_replace('\\', '/', trim((string)$path));
|
||||
if ($path === '') return '';
|
||||
$parts = array_values(array_filter(explode('/', $path), static fn($p) => $p !== ''));
|
||||
return implode('/', array_map('rawurlencode', $parts));
|
||||
}
|
||||
function video_thumb_public_url($config, $videoName){
|
||||
$videoName = basename((string)$videoName);
|
||||
if ($videoName === '') return '';
|
||||
$base = pathinfo($videoName, PATHINFO_FILENAME);
|
||||
foreach (['jpg','jpeg','png','webp','gif'] as $ext) {
|
||||
$file = $config['videos_dir'] . '/' . $base . '_thumb.' . $ext;
|
||||
if (is_file($file)) return $config['public_videos'] . '/' . rawurlencode($base . '_thumb.' . $ext) . '?v=' . filemtime($file);
|
||||
$info = video_thumb_source_info($config, $videoName);
|
||||
$sourcePath = (string)($info['source_path'] ?? '');
|
||||
if ($sourcePath !== '') {
|
||||
$abs = str_starts_with($sourcePath, '/') ? $sourcePath : __DIR__ . '/' . ltrim($sourcePath, '/');
|
||||
if (is_file($abs)) return public_url_path($sourcePath) . '?v=' . filemtime($abs);
|
||||
}
|
||||
$sourceFile = basename((string)($info['source_file'] ?? ''));
|
||||
$inputDir = basename((string)($info['input_dir'] ?? ''));
|
||||
if ($sourceFile !== '' && $inputDir !== '') {
|
||||
$rel = 'in-dir/' . $inputDir . '/' . $sourceFile;
|
||||
$abs = __DIR__ . '/' . $rel;
|
||||
if (is_file($abs)) return public_url_path($rel) . '?v=' . filemtime($abs);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
|
@ -1003,6 +1045,19 @@ try {
|
|||
if (!$outputs) throw new RuntimeException('No rendered video found for this input directory yet.');
|
||||
|
||||
$src = $dir . '/' . $file;
|
||||
$thumbName = $articleId . '_og.jpg';
|
||||
$target = $config['videos_dir'] . '/' . $thumbName;
|
||||
if (is_file($target)) @unlink($target);
|
||||
if (!@copy($src, $target)) {
|
||||
file_put_contents($logFile, "Failed to copy thumbnail.\n", FILE_APPEND); // LOG 2
|
||||
throw new RuntimeException('Failed to write thumbnail.');
|
||||
}
|
||||
@chmod($target, 0664);
|
||||
|
||||
file_put_contents($logFile, "Thumbnail copied, now applying overlay...\n", FILE_APPEND); // LOG 3
|
||||
|
||||
// Apply text overlay after smart resizing/cropping to 1200x630
|
||||
apply_thumbnail_overlay($target, (string)($meta['title'] ?? ''), (string)($meta['teaser'] ?? ''));
|
||||
$written = [];
|
||||
foreach ($outputs as $out) {
|
||||
$base = pathinfo($out, PATHINFO_FILENAME);
|
||||
|
|
@ -1011,25 +1066,13 @@ try {
|
|||
$old = $config['thumbs_dir'] . '/' . $base . '.' . $oldExt;
|
||||
if (is_file($old)) @unlink($old);
|
||||
}
|
||||
|
||||
// Copy new thumbnail to videos_dir with _thumb.jpg suffix
|
||||
$target = $config['videos_dir'] . '/' . $base . '_thumb.jpg';
|
||||
if (!@copy($src, $target)) {
|
||||
file_put_contents($logFile, "Failed to copy thumbnail.\n", FILE_APPEND); // LOG 2
|
||||
throw new RuntimeException('Failed to write thumbnail.');
|
||||
}
|
||||
@chmod($target, 0664);
|
||||
|
||||
file_put_contents($logFile, "Thumbnail copied, now applying overlay...\n", FILE_APPEND); // LOG 3
|
||||
|
||||
// Apply text overlay
|
||||
apply_thumbnail_overlay($target, (string)($meta['title'] ?? ''), (string)($meta['teaser'] ?? ''));
|
||||
|
||||
$thumbMeta = [
|
||||
'article_id' => $articleId,
|
||||
'input_dir' => basename($dir),
|
||||
'source_file' => $file,
|
||||
'source_path' => 'in-dir/' . basename($dir) . '/' . $file,
|
||||
'thumb_file' => $thumbName,
|
||||
'thumb_path' => 'out-dir/' . $thumbName,
|
||||
'created_at' => gmdate('c'),
|
||||
];
|
||||
$thumbMetaPath = $config['videos_dir'] . '/' . $base . '_thumb.json';
|
||||
|
|
@ -1037,7 +1080,6 @@ try {
|
|||
throw new RuntimeException('Failed to write thumbnail metadata.');
|
||||
}
|
||||
@chmod($thumbMetaPath, 0664);
|
||||
|
||||
$written[] = basename($target);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue