option('max-size'); $maxSizeBytes = $maxSizeKB * 1024; $this->info("正在优化 {$directory} 目录下的图片..."); $this->info("目标文件大小: {$maxSizeKB}KB"); $images = $disk->allFiles($directory); $total = count($images); $count = 0; $progressBar = $this->output->createProgressBar($total); $progressBar->start(); foreach ($images as $imagePath) { $originalSize = $disk->size($imagePath); $fileExtension = pathinfo($imagePath, PATHINFO_EXTENSION); // 只处理WEBP格式文件 if (strtolower($fileExtension) !== 'webp') { $this->warn("跳过非WEBP文件: $imagePath"); $progressBar->advance(); continue; } // 如果已经小于目标大小,则跳过 if ($originalSize <= $maxSizeBytes) { $progressBar->advance(); continue; } // 获取文件的绝对路径 $filePath = $disk->path($imagePath); // 创建压缩实例 $imageService = app(ImageService::class); $tempPath = storage_path('app/temp/'.basename($imagePath)); // 创建目标目录 if (!file_exists(dirname($tempPath))) { mkdir(dirname($tempPath), 0755, true); } // 多轮压缩策略 $currentSize = $originalSize; $iterations = 0; $currentQuality = (int)$this->option('quality'); $minQuality = (int)$this->option('min-quality'); $maxIterations = (int)$this->option('max-iterations'); while ($currentSize > $maxSizeBytes && $iterations < $maxIterations && $currentQuality >= $minQuality) { // 使用服务类进行压缩 $optimizedContent = $this->recompressImage( $filePath, $currentQuality ); file_put_contents($tempPath, $optimizedContent); $newSize = filesize($tempPath); // 如果新文件大小没有减小,则停止优化 if ($newSize >= $currentSize) { $this->warn("无法进一步压缩: $imagePath (质量: $currentQuality)"); break; } $currentSize = $newSize; $iterations++; // 降低质量进行下一轮尝试 if ($currentSize > $maxSizeBytes) { $currentQuality -= 5; } } // 替换原始文件 if ($currentSize < $originalSize) { rename($tempPath, $filePath); $this->info("优化成功: $imagePath 从 {$this->formatBytes($originalSize)} 压缩到 {$this->formatBytes($currentSize)}"); } else { @unlink($tempPath); $this->warn("压缩失败: $imagePath 无法达到目标大小"); } $progressBar->advance(); $count++; } $progressBar->finish(); $this->info("\n{$count}/{$total} 个图片已优化完成"); } /** * 重新压缩图片 */ protected function recompressImage($filePath, $quality) { // 读取原始图片 $image = imagecreatefromwebp($filePath); // 捕捉错误 if (!$image) { throw new \Exception("无法读取图片: $filePath"); } // 捕捉输出 ob_start(); $success = imagewebp($image, null, $quality); if (!$success) { throw new \Exception("压缩失败: $filePath"); } $compressedContent = ob_get_clean(); imagedestroy($image); return $compressedContent; } /** * 格式化字节大小 */ protected function formatBytes($bytes) { if ($bytes < 1024) return $bytes . 'B'; if ($bytes < 1048576) return round($bytes / 1024, 1) . 'KB'; return round($bytes / 1048576, 1) . 'MB'; } }