程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> GD庫使用小結---2,gd小結---2

GD庫使用小結---2,gd小結---2

編輯:關於PHP編程

GD庫使用小結---2,gd小結---2


  接著上一篇。GD庫可以折騰很多用法出來,當然得跟畫圖相關,除了前面的驗證碼、水印外,還可以進行圖片的縮放,裁剪、旋轉等操作,這在很多應用中可以見到。

  1. 加水印

  前面已經知道,我們可以使用imagechar或者imagestring等將字符或字符串(甚至中文字符)繪制到圖像上,以達到水印的目的,還有個更好的方式,不僅能加字符水印,還能加圖片水印:imagecopy。

  原型:bool imagecopy (resource $dst_im , resource $src_im , int $dst_x , int $dst_y , int $src_x , int $src_y , int $src_w , int $src_h),看名字知道這是復制,第1、2個參數分別是目標圖像句柄、源文件句柄,加水印時,如果水印圖片是一張小圖,加在一張大圖上面,那麼第一個參數就是大圖句柄,第二個參數就是小圖句柄。第3、4個參數是水印在目標圖像上的x、y坐標值,第5、6個參數是水印圖片上開始的x、y坐標值,第7、8個參數是水印圖片即將要作為水印的寬和高,因此這個方法的意思就是,將水印圖像src_im上左上角頂點坐標為(src_x, src_y)處,寬和高分別為src_w、src_h的部分復制到圖像dst_im上,再將這個dst_im圖像畫到畫布上保存或輸出,即為加過水印後的圖片了,代碼:

<?php
    
    date_default_timezone_set('Asia/Shanghai');
    define('DS', DIRECTORY_SEPARATOR);
    // 加水印,文字、圖片水印,以圖片為例
    function watermark($srcFile = '',  $markFile = '', $dstFile = '')
    {
        if(!file_exists($srcFile) || !file_exists($markFile))
        {
            echo 'file not exists!<br/>';
            return false;
        }
        // 獲取原始圖片與水印圖片的寬高
        list($srcWidth, $srcHeight) = getimagesize($srcFile);
        list($markWidth, $markHeight) = getimagesize($markFile);
        // 水印圖片不能比原始圖片像素還大
        if($markWidth > $srcWidth || $markHeight > $srcHeight)
        {
            return false;
        }
        // 獲取即將被加水印的原始圖片句柄、水印圖片句柄
        $dstImg = imagecreatefromjpeg($srcFile);
        $markImg = imagecreatefrompng($markFile);
        // 加水印的位置,簡單放在右下角
        $dst_x = $srcWidth - $markWidth;
        $dst_y = $srcHeight - $markHeight;
        // 獲取文件信息
        $fileinfo = pathinfo($srcFile);
        if(empty($dstFile))
        {
            $dstFile = rtrim($fileinfo['dirname'], DS).DS.'mark_'.$fileinfo['filename'].date('YmdHis').mt_rand(1, 1000).'.jpeg';
        }
        // 將水印圖片復制到已有圖片上
        imagecopy($dstImg, $markImg, $dst_x, $dst_y, 0, 0, $srcWidth, $srcHeight);
        // 將新加完水印的圖片保存起來
        imagejpeg($dstImg, $dstFile);
        imagedestroy($dstImg);
        imagedestroy($markImg);
        return true;
    }
    
    $srcFile = 'G:\wamp\www\html\image\p125.jpg';  // 原圖片
    $markFile = 'G:\wamp\www\html\image\ooopic_5.png'; // 水印圖片
    watermark($srcFile, $markFile);

  效果:      

在這裡,簡單將水印圖片放在圖片右下角,所以放在圖片的右下角要一個簡單的計算,調用imagecopy時,從水印圖片的左上角頂點(坐標0,0)開始全部(寬高傳入水印圖片寬高)復制到待加水印圖片上,然後imagejpeg繪制圖像並保存,注意類似imagejpeg(這裡簡單使用它)等繪圖函數傳入第二個參數時是保存圖片為一個文件,而不是輸出到浏覽器,所以也不需調header函數發送頭信息。

  當然還要搞清楚哪是源文件(src),哪是目標文件(dst),把一張小圖加水印到一張大圖上時,源文件是小圖水印,把它復制到大圖上,大圖就是目標。

   能用圖片作為水印,在於imagecopy的第二個參數是圖像句柄,所以可以從現有圖片來創建一個(如imagecreatefromjpeg),當然也能從現有的字符創建一個字符圖像句柄變量---使用imagecreatefromstring方法,所以這個更通用。

  2. 圖片縮放

  很多應用,圖片列表是小圖,當你點擊某一個時,才會展現完整大圖,這涉及到一個圖片收縮的處理。有兩個方法可供使用:imagecopyresized和imagecopyresampled,幾乎一樣,不同的是後者對圖片進行重采樣(貌似是我專業的詞),所以成圖質量更好(重采樣的話也得看采取哪種方法,有的會變得更渣),挑一個說:

  bool imagecopyresampled ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )

  第一、二個參數與上面相似,如何做到縮放?比如這裡,是將原圖像上左上角頂點處,坐標為(src_x, src_y),寬高為src_w、src_h的部分圖片,畫到目標圖像上坐標為(dst_x, dst_y),寬高為dst_w、dst_h的地方,所以如果目標圖片上的寬高比原圖上選取部分的寬高小的話,就成了縮小版了,當然還需要兩個左上角頂點的坐標值相同,以jpg類型為例:

<?php
    date_default_timezone_set('Asia/Shanghai');
    define('DS', DIRECTORY_SEPARATOR);
    // 縮小圖片
    /**
     * @param src 原圖像路徑
     * @param percent 縮小比例
     * @param dstFile 保存圖片的路徑
     */
    function zoomPic($srcFile = '', $percent = 0.5, $dstFile = '')
    {
        if(!file_exists($srcFile))
        {
            return false;
        }

        list($width, $height) = getimagesize($srcFile); // 獲取寬高
        ($percent <= 0 || $percent > 1) && $percent = 0.5;
        $newWidth = floor($width * $percent);    // 縮小後的寬高
        $newHeight = floor($height * $percent);
        
        $dstImg = imagecreatetruecolor($newWidth, $newHeight); // 創建新圖像寬高的畫布
        $srcImg = imagecreatefromjpeg($srcFile);  // 從原圖像文件創建畫布
        
        $pathinfo = pathinfo($srcFile);
        if(!$dstFile) $dstFile = rtrim($pathinfo['dirname'], DS).DS.'zoom_'.$pathinfo['filename'].date('YmdHis').mt_rand(1, 1000).".jpeg";
        // 從源文件左上角頂點開始進行縮小
        //imagecopyresized($dstImg, $srcImg, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); 
        imagecopyresampled($dstImg, $srcImg, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); 
        // 繪制且保存圖像
        imagejpeg($dstImg, $dstFile);
        // 銷毀資源
        imagedestroy($dstImg);
        imagedestroy($srcImg);
        return true;
    }
    // 測試
    $srcFile = 'G:\wamp\www\html\image\p179.jpg';
    zoomPic($srcFile);

  效果:  

  在這裡,我們可以將原圖與小圖分兩套存放,列表展示小圖,低級查就展示原圖。

  3. 圖片裁剪

  考慮上面的imagecopyresampled方法,如果不從原圖像的左上角開始,而是左上角偏右下某一點開始,切圖的寬高也再等於源文件完整的寬高,而是部分寬高,那麼新的重采樣的圖片,就是源圖片的一部分,就達到了裁剪的效果,所以裁剪與縮放使用的方法一樣

  

<?php
    date_default_timezone_set('Asia/Shanghai');
    define('DS', DIRECTORY_SEPARATOR);
    // cut a picture
    function cutPic($srcFile = '', $x = 0, $y = 0, $width = 16, $height = 16, $dstFile = '')
    {
        if(!file_exists($srcFile))
        {
            return false;
        }
        list($srcWidth, $srcHeight, $type) = getimagesize($srcFile);
        $x < 0 && $x = 0;
        $y < 0 && $y = 0;
        // 寬高設置
        (($width + $x) > $srcWidth) && $width = $srcWidth; 
        (($height + $y) > $srcHeight) && $height = $srcHeight;
        ($width <= 0) && $width = $srcWidth; 
        ($height <= 0) && $height = $srcHeight;

        $dstImg = imagecreatetruecolor($width, $height);  // 目標文件資源 
        switch($type)
        {
            case IMG_GIF:
                $srcImg = imagecreatefromgif($srcFile);  // 獲取源文件資源句柄及擴展名處理,以使用合適的函數和擴展
                $ext = 'gif';
                $imagefun = 'imagegif';
                break;
            case IMG_JPG:
                $srcImg = imagecreatefromjpeg($srcFile);  
                $ext = 'jpeg';
                $imagefun = 'imagejpeg';
                break;
            default:
                $srcImg = imagecreatefrompng($srcFile);  
                $ext = 'png';
                $imagefun = 'imagepng';
                break;
        }
        // 設置保存剪切後的文件路徑
        $fileinfo = pathinfo($srcFile);
        if(empty($dstFile))
        {
            $dstFile = rtrim($fileinfo['dirname'], DS).DS.'cut_'.$fileinfo['filename'].date('YmdHis').mt_rand(1, 1000).".{$ext}";
        }
        // 執行剪切操作
        imagecopyresampled($dstImg, $srcImg, 0, 0, $x, $y, $width, $height, $width, $height);
        // 畫於畫布並保存文件
        $imagefun($dstImg, $dstFile);
        imagedestroy($dstImg);
        imagedestroy($srcImg);
        return true;
    }
    // 測試
    $srcFile = 'G:\wamp\www\html\image\p221.jpg';
    cutPic($srcFile, 50, 50, 50, 50);

  效果:    

  常見的應用是,我們在給自己的某個應用換頭像時,頭像太大,就會用到裁剪,用這就可以做一個模擬實現。

  4. 圖片旋轉

  圖片旋轉也十分常見,主要用到函數imagerotate,原型:resource imagerotate ( resource $image , float $angle , int $bgd_color [, int $ignore_transparent = 0 ] ),第一個參數是待旋轉圖像句柄,第二個參數angle 是旋轉的角度數值,第三個參數指定一個顏色,即當旋轉後出現空的地方是使用哪種顏色填充,第四個參數是指定一個透明色,默認0表示保留透明色。該方法返回一個新的圖像句柄,就是經過旋轉後的圖像資源變量,將它繪制保存即可。還要注意的是,旋轉的角度可以指定0到360之間,為逆時針旋轉,以jpg為例:

<?php
    
    date_default_timezone_set('Asia/Shanghai');
    define('DS', DIRECTORY_SEPARATOR);
    /**
     * 圖片旋轉
     * @param angular 旋轉角度值 0-360
     */
    function rotatePic($srcFile = '', $angular = 0, $dstFile = '')
    {
        if(!file_exists($srcFile))
        {
            echo 'file not exists<br/>';
            return false;
        }

        $srcImg = imagecreatefromjpeg($srcFile);
        // 處理保存文件地址
        $fileinfo = pathinfo($srcFile);
        if(empty($dstFile))
        {
            $dstFile = rtrim($fileinfo['dirname'], DS).DS.'rotate_'.$fileinfo['filename'].date('YmdHis').mt_rand(1, 1000).'.jpeg';
        }
        
        $white = imagecolorallocate($srcImg, 0xff, 0xff, 0xf1);
        // 執行旋轉,注意是逆時針方向
        $dstImg = imagerotate($srcImg, $angular, $white);  
        // 畫到畫布,保存文件
        imagejpeg($dstImg, $dstFile);
        imagedestroy($dstImg);
        imagedestroy($srcImg);
        return true;
    }
    // 測試
    $srcFile = 'G:\wamp\www\html\image\p219.jpg';
    rotatePic($srcFile, 220);

  效果:原圖     旋轉後

  5. 圖片翻轉

  這個在應用中不那麼常見。所謂翻轉,就是對圖像進行鏡面翻轉,比如以圖片中間豎直線為軸線,左邊換到右邊,右邊換到左邊,對調一下位置,就是左右翻轉。想象一下,以中間豎直線為對稱軸的情況,Y軸像素點不變,X軸上的像素點左右對調,仍可以使用imagecopy方法,對於源文件,在復制到目標圖像時,進行這個操作,以繞Y軸旋轉,jpg類型圖片為例

<?php
    // 圖片翻轉
    date_default_timezone_set('Asia/Shanghai');
    define('DS', DIRECTORY_SEPARATOR);
    // 沿Y軸翻轉,x坐標值對調
    function turnY($srcFile = '', $dstFile = '')
    {
        if(!file_exists($srcFile))
        {
            return false;
        }
        // 原圖像句柄和寬高獲取
        $srcImg = imagecreatefromjpeg($srcFile);
        $srcWidth = imagesx($srcImg);
        $srcHeight = imagesy($srcImg);
        
        $dstImg = imagecreatetruecolor($srcWidth, $srcHeight);
        // 沿Y軸翻轉,x軸上的像素點左右對調
        for($i = 0; $i < $srcWidth; $i++)
        {
            imagecopy($dstImg, $srcImg, $srcWidth-$i-1, 0, $i, 0, 1, $srcHeight);
        }
        // 畫像保存路徑處理
        $fileinfo = pathinfo($srcFile);
        if(empty($dstFile))
        {
            $dstFile = rtrim($fileinfo['dirname'], DS).DS.'turnx_'.$fileinfo['filename'].date('YmdHis').mt_rand(1, 1000).'.jpeg';
        }
        // 繪制圖像,保存文件
        imagejpeg($dstImg, $dstFile);
        imagedestroy($dstImg);
        imagedestroy($srcImg);
        return false;
    }    
    // 測試
    $srcFile = 'G:\wamp\www\html\image\p311.jpg';
    turnY($srcFile);

  效果: 翻轉前  翻轉後 

  主要就是for循環那兒,得到源文件的寬度$srcWidth後,如果源文件上坐標是($i, 0)則對應目標圖像上坐標($srcWidth-$i-1, 0),然後將寬度為1個像素,高為源文件整個高度$srcHeight的資源復制過去,循環完成後就全部復制到一個圖片上了,相當於是一條一條線的畫過去的。

  無意浏覽手冊感覺被坑,看到imageflip函數猜到是這個功能,一看果然是的,可是看的書已經落後幾年了,原型:bool imageflip ( resource $image , int $mode ),第一個參數是目標圖像資源,第二個參數是翻轉的方式,使用php自帶的枚舉變量即可,有IMG_FLIP_HORIZONTAL(水平)、IMG_FLIP_HORIZONTAL(豎直)、IMG_FLIP_BOTH(水平豎直)三種方式,一個函數即可實現。

  反正都挺簡單,不如練練手玩玩 :-D

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved