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 ?>