ImageCompressService.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <?php
  2. namespace app\common\service;
  3. use Exception;
  4. class ImageCompressService
  5. {
  6. /**
  7. * 压缩图片
  8. * @param string $sourcePath 源文件路径
  9. * @param int $quality 压缩质量 (1-100)
  10. * @param int $maxWidth 最大宽度
  11. * @param int $maxHeight 最大高度
  12. * @return string|false 压缩后的文件路径
  13. */
  14. public static function compress($sourcePath, $quality = 80, $maxWidth = 1920, $maxHeight = 1080)
  15. {
  16. try {
  17. outFileLog($sourcePath,'upload_img','$sourcePath1');
  18. // 获取图片信息
  19. $imageInfo = getimagesize($sourcePath);
  20. outFileLog($imageInfo,'upload_img','imgInfo');
  21. if (!$imageInfo) {
  22. throw new Exception('无法获取图片信息');
  23. }
  24. $width = $imageInfo[0];
  25. $height = $imageInfo[1];
  26. $type = $imageInfo[2];
  27. outFileLog($width,'upload_img','$width');
  28. outFileLog($height,'upload_img','$height');
  29. // 如果图片尺寸已经很小,且质量要求不高,直接返回原文件
  30. if ($width <= $maxWidth && $height <= $maxHeight && $quality >= 90) {
  31. return $sourcePath;
  32. }
  33. outFileLog($sourcePath,'upload_img','$sourcePath2');
  34. // 计算新尺寸
  35. $newSize = self::calculateNewSize($width, $height, $maxWidth, $maxHeight);
  36. $newWidth = $newSize['width'];
  37. $newHeight = $newSize['height'];
  38. outFileLog($newWidth,'upload_img','$newWidth');
  39. outFileLog($newHeight,'upload_img','$newHeight');
  40. // 创建源图片资源
  41. $sourceImage = self::createImageFromType($sourcePath, $type);
  42. if (!$sourceImage) {
  43. throw new Exception('不支持的图片格式');
  44. }
  45. outFileLog($sourceImage,'upload_img','$sourceImage');
  46. // 创建新图片资源
  47. $newImage = imagecreatetruecolor($newWidth, $newHeight);
  48. outFileLog($newImage,'upload_img','$newImage');
  49. // 处理透明背景(PNG/GIF)
  50. if ($type == IMAGETYPE_PNG || $type == IMAGETYPE_GIF) {
  51. imagealphablending($newImage, false);
  52. imagesavealpha($newImage, true);
  53. $transparent = imagecolorallocatealpha($newImage, 255, 255, 255, 127);
  54. imagefill($newImage, 0, 0, $transparent);
  55. }
  56. // 重新采样
  57. imagecopyresampled($newImage, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
  58. // 生成压缩后的文件路径
  59. $compressedPath = self::generateCompressedPath($sourcePath);
  60. outFileLog($compressedPath,'upload_img','$compressedPath');
  61. // 保存压缩后的图片
  62. $result = self::saveImageByType($newImage, $compressedPath, $type, $quality);
  63. utFileLog($result,'upload_img','$result');
  64. // $imageInfo = getimagesize($result);
  65. // 释放内存
  66. imagedestroy($sourceImage);
  67. imagedestroy($newImage);
  68. return $result ? $compressedPath : false;
  69. } catch (Exception $e) {
  70. return false;
  71. }
  72. }
  73. /**
  74. * 计算新尺寸(保持宽高比)
  75. */
  76. private static function calculateNewSize($width, $height, $maxWidth, $maxHeight)
  77. {
  78. $ratio = min($maxWidth / $width, $maxHeight / $height, 1);
  79. return [
  80. 'width' => intval($width * $ratio),
  81. 'height' => intval($height * $ratio)
  82. ];
  83. }
  84. /**
  85. * 根据图片类型创建图片资源
  86. */
  87. private static function createImageFromType($path, $type)
  88. {
  89. switch ($type) {
  90. case IMAGETYPE_JPEG:
  91. return imagecreatefromjpeg($path);
  92. case IMAGETYPE_PNG:
  93. return imagecreatefrompng($path);
  94. case IMAGETYPE_GIF:
  95. return imagecreatefromgif($path);
  96. case IMAGETYPE_WEBP:
  97. return imagecreatefromwebp($path);
  98. default:
  99. return false;
  100. }
  101. }
  102. /**
  103. * 根据图片类型保存图片
  104. */
  105. private static function saveImageByType($image, $path, $type, $quality)
  106. {
  107. switch ($type) {
  108. case IMAGETYPE_JPEG:
  109. return imagejpeg($image, $path, $quality);
  110. case IMAGETYPE_PNG:
  111. // PNG压缩级别 0-9,质量参数需要转换
  112. $pngQuality = intval((100 - $quality) / 10);
  113. return imagepng($image, $path, $pngQuality);
  114. case IMAGETYPE_GIF:
  115. return imagegif($image, $path);
  116. case IMAGETYPE_WEBP:
  117. return imagewebp($image, $path, $quality);
  118. default:
  119. return false;
  120. }
  121. }
  122. /**
  123. * 生成压缩后的文件路径
  124. */
  125. private static function generateCompressedPath($originalPath)
  126. {
  127. $pathInfo = pathinfo($originalPath);
  128. return $pathInfo['dirname'] . '/' . $pathInfo['filename'] . '_compressed.' . $pathInfo['extension'];
  129. }
  130. }