zoukankan      html  css  js  c++  java
  • 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 ?> 
  • 相关阅读:
    Linux
    CUDA开发
    Linux C++
    Python
    C++
    模式识别
    Linux
    算法
    算法
    leetcode 数组,链表,跳表
  • 原文地址:https://www.cnblogs.com/CheeseZH/p/4566068.html
Copyright © 2011-2022 走看看