0, 'message' => '无法读取上传的文件', ]; } // 获取图片信息 $imageInfo = getimagesizefromstring($imageData); if (!$imageInfo) { return [ 'code' => 0, 'message' => '无法解析图片信息', ]; } // 确定原始和目标格式 $originalMimeType = $imageInfo['mime']; $originalExtension = image_type_to_extension($imageInfo[2], false); if ($targetFormat === null) { $targetFormat = $originalExtension; } // 创建图片资源 switch (strtolower($originalExtension)) { case 'jpeg': case 'jpg': $image = imagecreatefromstring($imageData); break; case 'png': $image = imagecreatefromstring($imageData); break; case 'webp': $image = imagecreatefromstring($imageData); break; default: return [ 'code' => 0, 'message' => '不支持的图片格式', ]; } if (!$image) { return [ 'code' => 0, 'message' => '无法创建图片资源', ]; } // 压缩并转换图片 ob_start(); switch (strtolower($targetFormat)) { case 'jpeg': case 'jpg': imagejpeg($image, null, $quality); $compressedMimeType = 'image/jpeg'; break; case 'png': $pngQuality = 9 - floor($quality / 11); imagepng($image, null, $pngQuality); $compressedMimeType = 'image/png'; break; case 'webp': if (function_exists('imagewebp')) { imagewebp($image, null, $quality); $compressedMimeType = 'image/webp'; } else { imagejpeg($image, null, $quality); $compressedMimeType = 'image/jpeg'; } break; default: imagedestroy($image); ob_end_clean(); return [ 'code' => 0, 'message' => "不支持的目标格式: {$targetFormat}", ]; } $compressedData = ob_get_clean(); imagedestroy($image); // 返回结果 return [ 'code' => 1, 'compressed_data' => $compressedData, 'base64' => 'data:' . $compressedMimeType . ';base64,' . base64_encode($compressedData), ]; } public function compressImage($filePath, $fileSize) { // 获取图片信息 $imageInfo = getimagesize($filePath); if (!$imageInfo) { return false; } $mime = $imageInfo['mime']; // 根据MIME类型创建图像资源 switch ($mime) { case 'image/jpeg': $image = imagecreatefromjpeg($filePath); break; case 'image/png': $image = imagecreatefrompng($filePath); break; case 'image/gif': $image = imagecreatefromgif($filePath); break; default: return false; } if (!$image) { return false; } // 计算压缩质量(根据文件大小动态调整) $originalQuality = 85; // 初始质量 $targetSize = 2.5 * 1024 * 1024; // 目标大小2.5MB // 如果文件很大,降低初始质量 if ($fileSize > 5 * 1024 * 1024) { $quality = 75; } elseif ($fileSize > 10 * 1024 * 1024) { $quality = 65; } else { $quality = $originalQuality; } // 创建临时文件 $tempFile = tempnam(sys_get_temp_dir(), 'compressed_'); // 保存压缩后的图片 switch ($mime) { case 'image/jpeg': imagejpeg($image, $tempFile, $quality); break; case 'image/png': // PNG使用压缩级别(0-9),需要转换 $pngQuality = 9 - round(($quality / 100) * 9); imagepng($image, $tempFile, $pngQuality); break; case 'image/gif': imagegif($image, $tempFile); break; } // 释放内存 imagedestroy($image); // 检查压缩后文件大小,如果仍然大于3MB,继续压缩 $compressedSize = filesize($tempFile); if ($compressedSize > 3 * 1024 * 1024) { // 递归压缩直到满足要求 return $this->compressImage($tempFile, $compressedSize); } return $tempFile; } }