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

PHP 面向對象實現圖片水印與縮略圖生成:支持 JPG/PNG/GIF、多種縮放模式、透明度控制

     編輯:PHP 綜合知識

類功能概覽

核心類 Water

<?php
class Water {
    // 水印配置
    private $watermark_on = '1';
    public $water_img;      // 水印圖片路徑
    public $pos = 1;        // 1-9 九宮格位置
    public $pct = 80;       // 圖片水印透明度 0-100
    public $quality = 80;   // JPEG 輸出質量
    public $text = '樂趣網zlblog.sinaapp.com'; // 文字水印內容
    public $size = 12;      // 文字大小
    public $color = '#000000';
    public $font = 'font.ttf';

    // 縮略圖配置
    private $thumb_on = 1;
    public $thumb_type = 1;     // 1-5 模式
    public $thumb_width;
    public $thumb_height;
    public $thumb_fix = '_dq';  // 輸出文件後綴

    // 驗證文件存在且為支持格式
    private function check($img) {
        $ext = strtolower(strrchr($img, '.'));
        return extension_loaded('gd') && file_exists($img) && in_array($ext, ['.jpg','.jpeg','.png','.gif']);
    }

    // ========== 縮略圖 ==========
    public function thumb($img, $outfile='', $t_type='', $t_w='', $t_h='') {
        if (!$this->check($img) || !$this->thumb_on) return false;

        $t_type = $t_type ?: $this->thumb_type;
        $t_w = $t_w ?: $this->thumb_width;
        $t_h = $t_h ?: $this->thumb_height;

        $info = getimagesize($img);
        $iw = $info[0]; $ih = $info[1];
        $ext = image_type_to_extension($info[2]); // .jpg/.png/.gif

        // 計算目標尺寸與裁切區域
        $size = $this->thumb_size($iw, $ih, $t_w, $t_h, $t_type);

        // 創建源圖資源
        $func = "imagecreatefrom".substr($ext, 1);
        $src = $func($img);

        // 創建目標資源 (GIF/PNG 用調色板保持透明)
        if (in_array($ext, ['.gif','.png'])) {
            $dst = imagecreate($size[0], $size[1]);
            $transparent = imagecolorallocate($dst, 255,0,0);
        } else {
            $dst = imagecreatetruecolor($size[0], $size[1]);
        }

        // 重採樣縮放
        if (function_exists('imagecopyresampled')) {
            imagecopyresampled($dst, $src, 0,0,0,0, $size[0],$size[1], $size[2],$size[3]);
        } else {
            imagecopyresized($dst, $src, 0,0,0,0, $size[0],$size[1], $size[2],$size[3]);
        }

        // 處理透明色
        if (in_array($ext, ['.gif','.png'])) imagecolortransparent($dst, $transparent);

        // 輸出文件
        $outfile = $outfile ?: substr($img,0,strripos($img,'.')).$this->thumb_fix.$ext;
        $ofunc = "image".substr($ext, 1);
        $ofunc($dst, $outfile);

        imagedestroy($dst); imagedestroy($src);
        return $outfile;
    }

    // 計算縮略圖尺寸邏輯
    private function thumb_size($iw,$ih,$tw,$th,$type) {
        $w=$tw; $h=$th; $cw=$iw; $ch=$ih;
        if ($iw<=$tw && $ih<$th) { $w=$iw; $h=$ih; }
        else {
            if ($type>0) {
                switch($type) {
                    case 1: $h = $tw/$iw*$ih; break;           // 寬固定,高等比
                    case 2: $w = $th/$ih*$iw; break;           // 高固定,寬等比
                    case 3: $ch = $iw/$tw*$th; break;          // 寬固定,高裁切
                    case 4: $cw = $ih/$th*$tw; break;          // 高固定,寬裁切
                    default: // 等比縮放
                        if (($iw/$tw) > ($ih/$th)) $h = $tw/$iw*$th;
                        elseif (($iw/$tw) < ($ih/$th)) $w = $th/$ih*$tw;
                        else { $w=$tw; $h=$th; }
                }
            }
        }
        return [$tw, $th, $cw, $ch];
    }

    // ========== 水印 ==========
    public function watermark($img, $pos='', $out_img='', $water_img='', $text='') {
        if (!$this->check($img) || !$this->watermark_on) return false;

        $water_img = $water_img ?: $this->water_img;
        $wm_on = $this->check($water_img) ? 1 : 0;
        $out_img = $out_img ?: $img;
        $pos = $pos ?: $this->pos;
        $text = $text ?: $this->text;

        $info = getimagesize($img);
        $iw = $info[0]; $ih = $info[1];

        // 水印資源
        if ($wm_on) {
            $winfo = getimagesize($water_img);
            $ww = $winfo[0]; $wh = $winfo[1];
            if ($iw < $ww || $ih < $wh) return false;
            $wfunc = "imagecreatefrom".substr(image_type_to_extension($winfo[2]),1);
            $wmark = $wfunc($water_img);
        } else {
            if (empty($text) || strlen($this->color)!=7) return false;
            $tbox = imagettfbbox($this->size, 0, $this->font, $text);
            $ww = $tbox[2]-$tbox[6]; $wh = $tbox[3]-$tbox[7];
        }

        // 源圖資源
        $sfunc = "imagecreatefrom".substr(image_type_to_extension($info[2]),1);
        $src = $sfunc($img);

        // 計算水印位置 (九宮格)
        switch($pos) {
            case 1: $x=$y=25; break;
            case 2: $x=($iw-$ww)/2; $y=25; break;
            case 3: $x=$iw-$ww; $y=25; break;
            case 4: $x=25; $y=($ih-$wh)/2; break;
            case 5: $x=($iw-$ww)/2; $y=($ih-$wh)/2; break;
            case 6: $x=$iw-$ww; $y=($ih-$wh)/2; break;
            case 7: $x=25; $y=$ih-$wh; break;
            case 8: $x=($iw-$ww)/2; $y=$ih-$wh; break;
            case 9: $x=$iw-$ww; $y=$ih-$wh; break;
            default: $x=mt_rand(25,$iw-$ww); $y=mt_rand(25,$ih-$wh);
        }

        // 繪製水印
        if ($wm_on) {
            imagecopymerge($src, $wmark, $x, $y, 0,0, $ww,$wh, $this->pct);
        } else {
            $r=hexdec(substr($this->color,1,2));
            $g=hexdec(substr($this->color,3,2));
            $b=hexdec(substr($this->color,5,2));
            $c = imagecolorallocate($src,$r,$g,$b);
            imagettftext($src, $this->size, 0, $x, $y, $c, $this->font, $text);
        }

        // 輸出
        $ofunc = "image".substr(image_type_to_extension($info[2]),1);
        $ofunc($src, $out_img);

        imagedestroy($src); if(isset($wmark)) imagedestroy($wmark);
        return true;
    }
}
?>

使用示例

$w = new Water();
$w->thumb_width = 300; $w->thumb_height = 200;
$w->thumb('photo.jpg');                    // 生成 photo_dq.jpg
$w->water_img = 'logo.png';
$w->watermark('photo.jpg', 9, 'photo_wm.jpg'); // 右下角圖片水印
$w->watermark('photo.jpg', 5, 'photo_text.jpg', '', '版權所有'); // 居中文字水印

關鍵技術點

  1. 格式自適應:image_type_to_extension + 動態函數名調用 (imagecreatefromjpeg 等)
  2. 透明保持:GIF/PNG 使用 imagecreate + imagecolortransparent
  3. 高質量縮放:優先 imagecopyresampled 雙三次插值
  4. 九宮格定位:1-9 對應左上到右下,含隨機模式
  5. 混合模式:圖片水印用 imagecopymerge 支持透明度,文字用 imagettftext

總結

Water 類將 GD 庫圖片處理封裝為水印與縮略圖兩大核心功能,支持主流格式、多種縮放策略、靈活定位與透明度控制。代碼結構模塊化,易於擴展(如添加旋轉、濾鏡、圓角等)。生產環境建議加入錯誤異常處理、文件權限檢查、臨時文件清理機制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
功能方法關鍵特性
水印watermark()圖片/文字水印、9 種位置、透明度、輸出覆蓋或新文件
縮略圖thumb()5 種模式(寬固定/高固定/寬固定裁高/高固定裁寬/等比)、保持透明、自定義後綴