ZH奶酪:PHP圖片壓縮(TinyPNG在線API)和(使用Imagick擴展)


1、調用TinyPng網站提供的API

1.1、須知

(1)tinypng的官網:https://tinypng.com/

  不知道國內訪問會不會很慢,在Singapore打開這個網站很流暢;

(2)API key申請地址:https://tinypng.com/developers

  調用這個網站提供的API需要申請一個API key,輸入郵箱,它會把包含API key的網址發到你郵箱,打開其中的鏈接就可以看到屬於你的API key了;

(3)調用這個網站的API進行圖片壓縮的話,每個月前500張是免費的,之后要收費;

(4)雖然域名是tinypng,但是既可以壓縮jpg圖片,也可以壓縮png圖片;

1.2、舉個栗子,代碼來啦~

 (1) class TinyImg 是我自己寫的一個類,包含下面三個方法:

  《1》壓縮文件夾下全部圖片

     public function compressImgsFolder($key,$inputFolder,$outputFolder) 是用來壓縮文件夾 $inputFolder (目錄路徑)中的圖片,保存到文件夾 $outputFolder (目錄路徑)中,其中 $key 就是上邊申請的API key;

  《2》壓縮單張圖片

     public function compressImg($key, $input, $output) 將輸入的圖片 $input (圖片路徑)進行壓縮並保存到圖片 $output (圖片路徑);

    這個函數中的代碼是從官網調用示例中提取出來的,初始的時候,line40是被注釋掉的,直接使用會出錯,我們需要

    <1> 去掉注釋;

    <2> 到http://curl.haxx.se/ca/cacert.pem把這個網頁(文本)保存(Ctrl+S)到class TinyImg 類文件的同一目錄下;

  《3》獲取文件夾下全部圖片的名字

     public function getFiles($filedir) 獲取$filedir下的全部圖片的名字列表;

 1 <?php
 2 /**
 3  * Created by PhpStorm.
 4  * User: Zhang He
 5  * Date: 2015/6/8
 6  * Time: 10:14
 7  */
 8 
 9 class TinyImg {
10     /*Compress all images in folder $inputFolder and save final images in folder $outputFolder*/
11     public function compressImgsFolder($key,$inputFolder,$outputFolder){
12         $images = $this->getFiles($inputFolder);
13         if(empty($images)){
14            return false;
15         }
16         foreach($images as $image){
17             $input = $inputFolder."\\".$image;
18             $output = $outputFolder."\\".$image;
19             print($input."<br>");
20             print($output."<br>");
21             $this->compressImg($key,$input,$output);
22         }
23         return true;
24     }
25     /*Compress one image $input and save as $output*/
26     public function compressImg($key, $input, $output){
27         $url = "https://api.tinify.com/shrink";
28         $options = array(
29             "http" => array(
30                 "method" => "POST",
31                 "header" => array(
32                     "Content-type: image/png",
33                     "Authorization: Basic " . base64_encode("api:$key")
34                 ),
35                 "content" => file_get_contents($input)
36             ),
37             "ssl" => array(
38                 /* Uncomment below if you have trouble validating our SSL certificate.
39                    Download cacert.pem from: http://curl.haxx.se/ca/cacert.pem */
40                 "cafile" => __DIR__ . "/cacert.pem",
41                 "verify_peer" => true
42             )
43         );
44 
45         $result = fopen($url, "r", false, stream_context_create($options));
46         if ($result) {
47             /* Compression was successful, retrieve output from Location header. */
48             foreach ($http_response_header as $header) {
49                 if (strtolower(substr($header, 0, 10)) === "location: ") {
50                     file_put_contents($output, fopen(substr($header, 10), "rb", false));
51                 }
52             }
53         } else {
54             /* Something went wrong! */
55             print("Compression failed<br>");
56         }
57     }
58     //get all files' fullname in $filedir
59     public function getFiles($filedir){
60         $files = [];
61         $dir = @dir($filedir);
62         while(($file = $dir->read())!= false){
63             if($file != "." and $file != ".."){
64                 $files[] = $file;
65             }
66         }
67         $dir->close();
68         return $files;
69     }
70 }

 (2) 測試代碼

 1 <?php  2 include("TinyImg.php");  3 /**  4  * Created by PhpStorm.  5  * User: Zhang He  6  * Date: 2015/6/8  7  * Time: 11:45  8 */  9 $tinyImg = new TinyImg(); 10 $key = "****HDtB9xgcry4tdcgbqkhLHs0****";//這里是你申請的API key 11 $input = "D:\\wamp\\www\\zh\\testTinyPng\\ibg_large_test"; //這個文件夾下的文件會被壓縮 12 $output = "D:\\wamp\\www\\zh\\testTinyPng\\ibg_small_test";//壓縮的結果會被保存到這個文件夾中 13 $tinyImg->compressImgsFolder($key,$input,$output);

 2、使用PHP的Imagick擴展

2.1、PHP圖像處理擴展包GD、Imagick、Gmagick對比

  GD屬於老古董級別的,丟掉吧,效率很低,而且壓縮的圖片體積很大。

  Imagick是個不錯的選擇,在PHP的圖片處理擴展中表現的很顯眼。不管是對jpg或png的靜態圖片,還是對gif的動態圖片,壓縮和縮小放大尺寸都非常給力。

  Gmagic沒怎么試過,而GraphicsMagick據說也是相當的給力,但網上很多評論基本上都是對效率的一些評測。

  安裝流程參考鏈接:http://blog.csdn.net/lyd518/article/details/6753476

 1 wget ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick-6.5.2-7.tar.gz
 2 tar -zxvf ImageMagick-6.5.2-7.tar.gz
 3 cd ImageMagick-6.5.2-7/
 4 ./configure
 5 make
 6 make install
 7 #譯PHP原生庫Imagick
 8 wget http://pecl.php.net/get/imagick-2.2.2.tgz
 9 tar zxvf imagick-2.2.2.tgz
10 cd imagick-2.2.2/
11 /usr/local/webserver/php/bin/phpize
12 ./configure --with-php-config=/usr/local/webserver/php/bin/php-config
13 make
14 make install
15 #最后,修改php.ini,加上(去除下面#號)
16 #extension = "imagick.so"

測試用例

1 //讀取pdf頁面的第一頁
2 $im = new Imagick('test.pdf');
3 //設置輸出圖片的格式
4 $im->setImageFormat('png');
5 //輸出圖片
6 header('Content-Type:image/png');
7 echo $im; 

 

2.2、優化前代碼

  這個代碼中的壓縮功能,主要依靠

    line18的 $imagick->cropThumbnailImage($width, $height);

    和line20的 $imagick->resizeImage($width, $height, Imagick::FILTER_LANCZOS, 1, true); 

    實現的壓縮。

 1 /**
 2  * 縮小圖片尺寸.
 3  *
 4  * @param $image 待處理的二進制圖片
 5  * @param $width 處理后圖片尺寸的寬度(px)
 6  * @param $height 處理后圖片尺寸的高度(px)
 7  * @param $crop 是否裁剪圖片
 8  *
 9  * @return 處理好的二進制圖片
10  */
11 function resize($image, $width, $height, $crop) {
12     $imagick = new \Imagick();
13     $imagick->readImageBlob($image);
14     $w = $imagick->getImageWidth();
15     $h = $imagick->getImageHeight();
16     if ($w > $width || $h > $height) {
17         if ($crop) {
18             $imagick->cropThumbnailImage($width, $height);
19         } else {
20             $imagick->resizeImage($width, $height, \Imagick::FILTER_LANCZOS, 1, true);
21         }
22     }
23     $processed_image = $imagick->getImageBlob();
24     return $processed_image;
25 }

 2.3 優化后代碼

 1     /*
 2      * User:Zhang He
 3      * Time:20150610
 4      * Function:Resize $src image and store as $dst
 5      * */
 6     public static function resize($src, $dst, $width=320, $height=320, $crop=false) {
 7 
 8         $imagick = new \Imagick($src);
 9 
10         $w = $imagick->getImageWidth();
11         $h = $imagick->getImageHeight();
12 
13         if ($w > $width || $h > $height) {
14 
15             if ($crop) {
16                 $imagick->cropThumbnailImage($width, $height);
17             } else {
18                 $imagick->resizeImage($width, $height, \Imagick::FILTER_CATROM, 1, true);
19             }
20         }
21 
22         $imagick->setImageFormat('JPEG');
23         $imagick->setImageCompression(\Imagick::COMPRESSION_JPEG);
24         $a = $imagick->getImageCompressionQuality() * 0.75;
25 
26         if ($a == 0) {
27             $a = 75;
28         }
29 
30         $imagick->setImageCompressionQuality($a);
31         $imagick->stripImage();
32 
33         $imagick->writeImage($dst);
34         $imagick->clear();
35         $imagick->destroy();
36     }

(1)參考文章

優化代碼集中在line22-line31,至於為什么這樣優化以及優化達到的效果,可以看原文鏈接(代碼沒有格式化):http://www.6a8a.com/2011/PHP_0402/939.html

(2)函數的作用

每個函數的含義可以到 http://php.net/manual/zh/class.imagick.php 查看,下面我列出最主要的幾個函數及其解釋。

bool Imagick::setImageFormat ( string $format )

  為圖片設置指定格式

支持的格式以及對應的庫,可以查看 http://www.imagemagick.org/script/formats.php

bool Imagick::setImageCompression ( int $compression )

  設置圖片壓縮的類型

Imagick中定義的常量,可以查看 http://php.net/manual/en/imagick.constants.php

bool Imagick::setImageCompressionQuality ( int $quality )

  設置圖片壓縮質量

bool Imagick::stripImage ( void )

  去掉圖片的所有配置和設置,如Exif

bool Imagick::resizeImage ( int $columns , int $rows , int $filter , float $blur [, bool $bestfit = false ] )

  通過過濾器將圖片縮放到期望的尺寸。

  過濾器也在Imagick定義的常量頁面可以找到:http://php.net/manual/zh/imagick.constants.php#imagick.constants.filters

  Note: 參數 bestfit 的特性在 Imagick 3.0.0 中已改變。在此版本以前,當目標尺寸設為 400x400 時,原尺寸為 200x150 的圖像將不會被改變。自 Imagick 3.0.0 起,源圖像將會被放大到 400x300 因為這將更好的適合目標尺寸。當使用參數 bestfit 時,必須同時給出寬度和高度。  

bool Imagick::cropThumbnailImage ( int $width , int $height )

  生成一個指定大小的縮略圖,首先放大或縮小圖片,然后裁剪出一個指定的區域從圖片中間。

示例代碼:

1 <?php
2 /* Read the image */
3 $im = new imagick( "test.png" );
4 /* create the thumbnail */
5 $im->cropThumbnailImage( 80, 80 );
6 /* Write to a file */
7 $im->writeImage( "th_80x80_test.png" );
8 ?>

(3)選擇哪個過濾器?

 將一個5906*5906的圖片壓縮至1181*1181所需時間對比:

 1 FILTER_POINT took: 0.334532976151 seconds
 2 FILTER_BOX took: 0.777871131897 seconds
 3 FILTER_TRIANGLE took: 1.3695909977 seconds
 4 FILTER_HERMITE took: 1.35866093636 seconds
 5 FILTER_HANNING took: 4.88722896576 seconds
 6 FILTER_HAMMING took: 4.88665103912 seconds
 7 FILTER_BLACKMAN took: 4.89026689529 seconds
 8 FILTER_GAUSSIAN took: 1.93553304672 seconds
 9 FILTER_QUADRATIC took: 1.93322920799 seconds
10 FILTER_CUBIC took: 2.58396601677 seconds
11 FILTER_CATROM took: 2.58508896828 seconds
12 FILTER_MITCHELL took: 2.58368492126 seconds
13 FILTER_LANCZOS took: 3.74232912064 seconds
14 FILTER_BESSEL took: 4.03305602074 seconds
15 FILTER_SINC took: 4.90098690987 seconds 

因此,CATROM在保證壓縮效果接近LANCZOS的同時,耗時也比較短。

(4)最簡潔代碼示例

我找到最簡潔的例子是這個:

 1 /*
 2 Imagick::setImageCompression
 3 Imagick::setImageCompressionQuality
 4 Imagick::stripImage
 5 Imagick::thumbnailImage
 6 Imagick::writeImage
 7 */
 8 
 9 <?php
10     $image = 'image.jpg';
11     $directory = '/path/to/image';
12     $image_location = $directory . "/" . $image;
13     $thumb_destination = $directory . "/t" . $image;
14     $compression_type = Imagick::COMPRESSION_JPEG;
15   
16     $im = new Imagick($image_location);
17     $thumbnail = $im->clone;
18 
19     $thumbnail->setImageCompression($compression_type);
20     $thumbnail->setImageCompressionQuality(40);
21     $thumbnail->stripImage();
22     $thumbnail->thumbnailImage(100,null);
23     $thumbnail->writeImage($thumb_destination);
24 ?> 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM