From 4ae2bb14a6db5ccedff91d115849d7ab9e745362 Mon Sep 17 00:00:00 2001 From: hashbro Date: Mon, 14 Sep 2026 02:15:02 +0800 Subject: [PATCH] fix: link old --- app/Services/PhotoPreview.php | 70 ++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/app/Services/PhotoPreview.php b/app/Services/PhotoPreview.php index 93da314..d10424a 100644 --- a/app/Services/PhotoPreview.php +++ b/app/Services/PhotoPreview.php @@ -131,6 +131,36 @@ class PhotoPreview return strlen($bytes) >= 3 && substr($bytes, 0, 2) === "\xFF\xD8"; } + /** + * heif-convert writes dest.jpg, or dest-1.jpg when the HEIC has multiple images. + */ + private function readConvertedJpeg(string $dst): ?string + { + $candidates = [$dst]; + $stem = preg_replace('/\.jpe?g$/i', '', $dst) ?? $dst; + foreach (glob($stem.'-*.jpg') ?: [] as $extra) { + $candidates[] = $extra; + } + $best = null; + $bestSize = 0; + foreach ($candidates as $path) { + if (! is_file($path) || filesize($path) < 3) { + continue; + } + $bytes = (string) file_get_contents($path); + if (! $this->isJpeg($bytes)) { + continue; + } + $size = strlen($bytes); + if ($size > $bestSize) { + $best = $bytes; + $bestSize = $size; + } + } + + return $best; + } + private function convertToJpeg(string $absPath): ?string { $src = null; @@ -160,11 +190,16 @@ class PhotoPreview ]); continue; } - if (! $result->successful() || ! is_file($dst) || filesize($dst) < 3) { + if (! $result->successful()) { + Log::warning('heic preview convert cmd failed', [ + 'path' => $absPath, + 'cmd' => implode(' ', $cmd), + 'stderr' => trim($result->errorOutput()), + ]); continue; } - $bytes = (string) file_get_contents($dst); - if ($this->isJpeg($bytes)) { + $bytes = $this->readConvertedJpeg($dst); + if ($bytes !== null) { return $bytes; } } @@ -181,8 +216,13 @@ class PhotoPreview if (is_string($src) && is_file($src)) { @unlink($src); } - if (is_string($dst) && is_file($dst)) { - @unlink($dst); + if (is_string($dst)) { + $stem = preg_replace('/\.jpe?g$/i', '', $dst) ?? $dst; + foreach (array_merge([$dst], glob($stem.'-*.jpg') ?: []) as $tmp) { + if (is_string($tmp) && is_file($tmp)) { + @unlink($tmp); + } + } } } } @@ -197,14 +237,22 @@ class PhotoPreview if (PHP_OS_FAMILY === 'Darwin' && $this->isSafeExecutable('/usr/bin/sips')) { $cmds[] = ['/usr/bin/sips', '-s', 'format', 'jpeg', '--out', $dst, $src]; } - foreach (['heif-convert', 'magick'] as $bin) { + foreach (['heif-convert', 'heif-dec'] as $bin) { $path = $this->resolveBinary($bin); if ($path === null) { continue; } - $cmds[] = $bin === 'magick' - ? [$path, $src, '-quality', '85', $dst] - : [$path, $src, $dst]; + $cmds[] = [$path, $src, $dst]; + $cmds[] = [$path, '-q', '85', $src, $dst]; + $cmds[] = [$path, $src, '-o', $dst]; + } + $magick = $this->resolveBinary('magick'); + if ($magick !== null) { + $cmds[] = [$magick, $src, '-quality', '85', $dst]; + } + $convert = $this->resolveBinary('convert'); + if ($convert !== null) { + $cmds[] = [$convert, $src, '-quality', '85', $dst]; } return $cmds; @@ -214,7 +262,9 @@ class PhotoPreview { $candidates = match ($name) { 'magick' => [base_path('bin/magick'), 'magick', '/opt/homebrew/bin/magick', '/usr/local/bin/magick', '/usr/bin/magick'], - 'heif-convert' => [base_path('bin/heif-convert'), 'heif-convert', '/opt/homebrew/bin/heif-convert', '/usr/local/bin/heif-convert', '/usr/bin/heif-convert'], + 'convert' => ['convert', '/usr/bin/convert'], + 'heif-convert' => [base_path('bin/heif-convert'), 'heif-convert', '/usr/bin/heif-convert', '/usr/local/bin/heif-convert'], + 'heif-dec' => [base_path('bin/heif-dec'), 'heif-dec', '/usr/bin/heif-dec', '/usr/local/bin/heif-dec'], default => [$name], }; $bare = null;