Explorar o código

压缩图片方法

moonsflyer hai 4 meses
pai
achega
2e28166285
Modificáronse 1 ficheiros con 137 adicións e 0 borrados
  1. 137 0
      app/common/service/ImageCompressService.php

+ 137 - 0
app/common/service/ImageCompressService.php

@@ -0,0 +1,137 @@
+<?php
+
+namespace app\common\service;
+
+use Exception;
+
+class ImageCompressService
+{
+    /**
+     * 压缩图片
+     * @param string $sourcePath 源文件路径
+     * @param int $quality 压缩质量 (1-100)
+     * @param int $maxWidth 最大宽度
+     * @param int $maxHeight 最大高度
+     * @return string|false 压缩后的文件路径
+     */
+    public static function compress($sourcePath, $quality = 80, $maxWidth = 1920, $maxHeight = 1080)
+    {
+        try {
+            // 获取图片信息
+            $imageInfo = getimagesize($sourcePath);
+            if (!$imageInfo) {
+                throw new Exception('无法获取图片信息');
+            }
+
+            $width = $imageInfo[0];
+            $height = $imageInfo[1];
+            $type = $imageInfo[2];
+
+            // 如果图片尺寸已经很小,且质量要求不高,直接返回原文件
+            if ($width <= $maxWidth && $height <= $maxHeight && $quality >= 90) {
+                return $sourcePath;
+            }
+
+            // 计算新尺寸
+            $newSize = self::calculateNewSize($width, $height, $maxWidth, $maxHeight);
+            $newWidth = $newSize['width'];
+            $newHeight = $newSize['height'];
+
+            // 创建源图片资源
+            $sourceImage = self::createImageFromType($sourcePath, $type);
+            if (!$sourceImage) {
+                throw new Exception('不支持的图片格式');
+            }
+
+            // 创建新图片资源
+            $newImage = imagecreatetruecolor($newWidth, $newHeight);
+            
+            // 处理透明背景(PNG/GIF)
+            if ($type == IMAGETYPE_PNG || $type == IMAGETYPE_GIF) {
+                imagealphablending($newImage, false);
+                imagesavealpha($newImage, true);
+                $transparent = imagecolorallocatealpha($newImage, 255, 255, 255, 127);
+                imagefill($newImage, 0, 0, $transparent);
+            }
+
+            // 重新采样
+            imagecopyresampled($newImage, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
+
+            // 生成压缩后的文件路径
+            $compressedPath = self::generateCompressedPath($sourcePath);
+
+            // 保存压缩后的图片
+            $result = self::saveImageByType($newImage, $compressedPath, $type, $quality);
+
+            // 释放内存
+            imagedestroy($sourceImage);
+            imagedestroy($newImage);
+
+            return $result ? $compressedPath : false;
+
+        } catch (Exception $e) {
+            return false;
+        }
+    }
+
+    /**
+     * 计算新尺寸(保持宽高比)
+     */
+    private static function calculateNewSize($width, $height, $maxWidth, $maxHeight)
+    {
+        $ratio = min($maxWidth / $width, $maxHeight / $height, 1);
+        return [
+            'width' => intval($width * $ratio),
+            'height' => intval($height * $ratio)
+        ];
+    }
+
+    /**
+     * 根据图片类型创建图片资源
+     */
+    private static function createImageFromType($path, $type)
+    {
+        switch ($type) {
+            case IMAGETYPE_JPEG:
+                return imagecreatefromjpeg($path);
+            case IMAGETYPE_PNG:
+                return imagecreatefrompng($path);
+            case IMAGETYPE_GIF:
+                return imagecreatefromgif($path);
+            case IMAGETYPE_WEBP:
+                return imagecreatefromwebp($path);
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * 根据图片类型保存图片
+     */
+    private static function saveImageByType($image, $path, $type, $quality)
+    {
+        switch ($type) {
+            case IMAGETYPE_JPEG:
+                return imagejpeg($image, $path, $quality);
+            case IMAGETYPE_PNG:
+                // PNG压缩级别 0-9,质量参数需要转换
+                $pngQuality = intval((100 - $quality) / 10);
+                return imagepng($image, $path, $pngQuality);
+            case IMAGETYPE_GIF:
+                return imagegif($image, $path);
+            case IMAGETYPE_WEBP:
+                return imagewebp($image, $path, $quality);
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * 生成压缩后的文件路径
+     */
+    private static function generateCompressedPath($originalPath)
+    {
+        $pathInfo = pathinfo($originalPath);
+        return $pathInfo['dirname'] . '/' . $pathInfo['filename'] . '_compressed.' . $pathInfo['extension'];
+    }
+}