['maxWidth' => 1600, 'quality' => 82], 'noticias' => ['maxWidth' => 1200, 'quality' => 82], 'promos' => ['maxWidth' => 1200, 'quality' => 82], 'clubes' => ['maxWidth' => 512, 'quality' => 85], 'sponsors' => ['maxWidth' => 600, 'quality' => 85], 'qr' => ['maxWidth' => 800, 'quality' => 85], ]; private const MIN_RECOMPRESS_BYTES = 100 * 1024; /** * Sube el archivo al disk 'public' y lo optimiza in-place. * Retorna el path relativo (ej: "carousel/abc123.jpg"). */ public function storeAndOptimize(UploadedFile $file, string $folder): string { $path = $file->store($folder, 'public'); if (!extension_loaded('gd')) { return $path; } $cfg = self::FOLDERS[$folder] ?? null; if (!$cfg) { return $path; } $abs = Storage::disk('public')->path($path); $this->optimizeFile($abs, $cfg['maxWidth'], $cfg['quality']); return $path; } /** * Optimiza un archivo en disco (resize + recompress). * Devuelve [origSize, newSize, newW, newH] o null si no se modifico. */ public function optimizeFile(string $file, int $maxWidth, int $quality): ?array { if (!file_exists($file)) return null; $origSize = filesize($file); $info = @getimagesize($file); if (!$info) return null; [$w, $h] = $info; $needsResize = $w > $maxWidth; $needsRecomp = $origSize > self::MIN_RECOMPRESS_BYTES; if (!$needsResize && !$needsRecomp) return null; $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); $img = match ($ext) { 'jpg', 'jpeg' => @imagecreatefromjpeg($file), 'png' => @imagecreatefrompng($file), 'webp' => @imagecreatefromwebp($file), default => null, }; if (!$img) return null; $newW = $w; $newH = $h; if ($w > $maxWidth) { $newW = $maxWidth; $newH = (int) round($h * ($maxWidth / $w)); $resized = imagecreatetruecolor($newW, $newH); if (in_array($ext, ['png', 'webp'])) { imagealphablending($resized, false); imagesavealpha($resized, true); $transparent = imagecolorallocatealpha($resized, 0, 0, 0, 127); imagefilledrectangle($resized, 0, 0, $newW, $newH, $transparent); } imagecopyresampled($resized, $img, 0, 0, 0, 0, $newW, $newH, $w, $h); $img = $resized; } ob_start(); match ($ext) { 'jpg', 'jpeg' => imagejpeg($img, null, $quality), 'png' => imagepng($img, null, 9), 'webp' => imagewebp($img, null, $quality), }; $bytes = ob_get_clean(); if (strlen($bytes) >= $origSize) { return null; } file_put_contents($file, $bytes); return [$origSize, strlen($bytes), $newW, $newH]; } }