首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 強大圖片處理類:水印、縮放、裁剪、旋轉、銳化、透明度、反色一站式解決

     編輯:PHP 相關知識

功能全面的 PHP 圖片處理類深度解析與使用指南

本文介紹一個功能極其豐富的 picture 類,整合了水印(文字/圖片)、縮放、裁剪、旋轉、翻轉、銳化、透明度調整、反色等核心圖片處理功能,採用「操作產生新圖、保留歷史」的設計思路,適合構建圖片編輯器、用戶頭像處理、水印批量加工等場景。

類能力矩陣

功能核心方法關鍵屬性
載入圖片建構子 __construct()$PICTURE_URL
文字水印_mark_text()$FONT_WORD, $FONT_SIZE, $FONT_COLOR, $FONT_PATH, $ANGLE
圖片水印_mark_picture()$FORCE_URL, $FORCE_X, $FORCE_Y
縮放zoom()$ZOOM, $ZOOM_MULTIPLE, $ZOOM_WIDTH, $ZOOM_HEIGHT
裁剪cut()$CUT_X, $CUT_Y, $CUT_WIDTH, $CUT_HEIGHT
銳化sharp()$SHARP
透明度alpha_()$ALPHA, $ALPHA_X, $ALPHA_Y
任意角度旋轉turn()$CIRCUMROTATE
水平/垂直翻轉turn_x(), turn_y()無
反色return_color()無
輸出/保存show(), save_picture()$DEST_URL

核心代碼精簡版(保留關鍵邏輯)

<?php
class Picture {
    private $srcImg;      // 原圖資源
    private $dstImg;      // 處理後資源
    private $info;        // [width, height, mime, type]

    public function __construct($path) {
        $this->info = getimagesize($path);
        if (!$this->info) throw new Exception("圖片不存在或格式不支援");
        $this->srcImg = $this->createFromPath($path);
    }

    private function createFromPath($path) {
        switch ($this->info[2]) {
            case IMAGETYPE_GIF:  return imagecreatefromgif($path);
            case IMAGETYPE_JPEG: return imagecreatefromjpeg($path);
            case IMAGETYPE_PNG:  return imagecreatefrompng($path);
            default: throw new Exception("不支援的圖片類型");
        }
    }

    /** 縮放:支援倍數或固定寬高 */
    public function zoom($scale = null, $width = null, $height = null) {
        $srcW = $this->info[0]; $srcH = $this->info[1];
        if ($scale) { $width = $srcW * $scale; $height = $srcH * $scale; }
        if (!$width) $width = $srcW;
        if (!$height) $height = $srcH;

        $this->dstImg = imagecreatetruecolor($width, $height);
        imagecopyresampled($this->dstImg, $this->srcImg, 0, 0, 0, 0, $width, $height, $srcW, $srcH);
        $this->replaceSrc();
        return $this;
    }

    /** 裁剪 */
    public function crop($x, $y, $width, $height) {
        $this->dstImg = imagecreatetruecolor($width, $height);
        imagecopy($this->dstImg, $this->srcImg, 0, 0, $x, $y, $width, $height);
        $this->replaceSrc();
        return $this;
    }

    /** 文字水印 */
    public function watermarkText($text, $fontPath, $fontSize = 20, $color = '#000000', $x = null, $y = null, $angle = 0) {
        $this->dstImg = imagecreatetruecolor($this->info[0], $this->info[1]);
        imagecopy($this->dstImg, $this->srcImg, 0, 0, 0, 0, $this->info[0], $this->info[1]);
        $rgb = $this->hex2rgb($color);
        $textColor = imagecolorallocate($this->dstImg, $rgb[0], $rgb[1], $rgb[2]);
        $box = imagettfbbox($fontSize, $angle, $fontPath, $text);
        $textW = $box[2] - $box[0];
        $textH = $box[3] - $box[7];
        $x = $x ?? $this->info[0] - $textW - 10;
        $y = $y ?? $this->info[1] - $textH - 10;
        imagettftext($this->dstImg, $fontSize, $angle, $x, $y, $textColor, $fontPath, $text);
        $this->replaceSrc();
        return $this;
    }

    /** 圖片水印 */
    public function watermarkImage($waterPath, $x = 0, $y = 0, $opacity = 100) {
        $waterInfo = getimagesize($waterPath);
        $water = $this->createFromPath($waterPath);
        $this->dstImg = imagecreatetruecolor($this->info[0], $this->info[1]);
        imagecopy($this->dstImg, $this->srcImg, 0, 0, 0, 0, $this->info[0], $this->info[1]);
        imagecopymerge($this->dstImg, $water, $x, $y, 0, 0, $waterInfo[0], $waterInfo[1], $opacity);
        $this->replaceSrc();
        return $this;
    }

    /** 旋轉 */
    public function rotate($angle, $bgColor = '#FFFFFF') {
        $rgb = $this->hex2rgb($bgColor);
        $bg = imagecolorallocate($this->srcImg, $rgb[0], $rgb[1], $rgb[2]);
        $this->dstImg = imagerotate($this->srcImg, $angle, $bg);
        $this->replaceSrc();
        return $this;
    }

    /** 銳化 */
    public function sharpen($amount = 7) {
        $this->dstImg = imagecreatetruecolor($this->info[0], $this->info[1]);
        $kernel = [
            [-1, -1, -1],
            [-1, 16, -1],
            [-1, -1, -1]
        ];
        imageconvolution($this->srcImg, $kernel, $amount, 0);
        $this->dstImg = $this->srcImg;
        return $this;
    }

    /** 輸出顯示 */
    public function output($quality = 90) {
        header("Content-Type: {$this->info['mime']}");
        switch ($this->info[2]) {
            case IMAGETYPE_JPEG: imagejpeg($this->srcImg, null, $quality); break;
            case IMAGETYPE_PNG:  imagepng($this->srcImg); break;
            case IMAGETYPE_GIF:  imagegif($this->srcImg); break;
        }
    }

    /** 保存文件 */
    public function save($path, $quality = 90) {
        switch ($this->info[2]) {
            case IMAGETYPE_JPEG: imagejpeg($this->srcImg, $path, $quality); break;
            case IMAGETYPE_PNG:  imagepng($this->srcImg, $path); break;
            case IMAGETYPE_GIF:  imagegif($this->srcImg, $path); break;
        }
    }

    private function replaceSrc() {
        imagedestroy($this->srcImg);
        $this->srcImg = $this->dstImg;
        $this->info[0] = imagesx($this->srcImg);
        $this->info[1] = imagesy($this->srcImg);
    }

    private function hex2rgb($hex) {
        $hex = ltrim($hex, '#');
        return [hexdec(substr($hex,0,2)), hexdec(substr($hex,2,2)), hexdec(substr($hex,4,2))];
    }

    public function __destruct() {
        if ($this->srcImg) imagedestroy($this->srcImg);
        if ($this->dstImg && $this->dstImg !== $this->srcImg) imagedestroy($this->dstImg);
    }
}

鏈式調用範例

<?php
require 'Picture.class.php';

$pic = new Picture('uploads/photo.jpg');
// 縮放 50% -> 加文字水印 -> 旋轉 15 度 -> 銳化 -> 保存
$pic->zoom(0.5)
    ->watermarkText('© MySite', 'fonts/msyh.ttc', 24, '#FF0000', 20, 20)
    ->rotate(15, '#F0F0F0')
    ->sharpen(5)
    ->save('output/photo_processed.jpg');

echo "處理完成!";

設計亮點與避坑指南

  1. 鏈式調用:每個方法返回 $this,支援流暢接口
  2. 資源管理:每步操作產生新圖資源,銷毀舊資源,避免記憶體洩漏
  3. 歷史記錄:若需撤銷/重做,可在 replaceSrc() 前將舊資源推入堆疊
  4. 透明度處理:PNG/GIF 透明通道在 imagecopyresampled、imagerotate 中自動保留,需注意背景色設置
  5. 字體路徑:使用絕對路徑,確保 imagettftext 能找到 TTF 文件
  6. 錯誤處理:建構子驗證 getimagesize,失敗拋出異常

擴展建議

  • 加入 filter() 支援濾鏡(灰階、模糊、浮雕)
  • 整合 Intervention/Image 或 Imagine 以獲得更現代的 API
  • 支援 WebP 輸出(imagewebp)
  • 增加批量處理靜態方法 Picture::batch($files, $operations)

這個類雖然代碼風格偏向 PHP 5 時代,但核心 GD 操作邏輯清晰、功能完整,經適當重構(命名空間、類型聲明、異常處理)即可投入現代項目使用,是理解 PHP 圖片處理底層原理的優秀教材。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved