ZH奶酪:PHP图片压缩(TinyPNG在线API)和(使用Imagick扩展)
2015-06-10 15:08
781 查看
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下的全部图片的名字列表;
<?php /** * Created by PhpStorm. * User: Zhang He * Date: 2015/6/8 * Time: 10:14 */ class TinyImg { /*Compress all images in folder $inputFolder and save final images in folder $outputFolder*/ public function compressImgsFolder($key,$inputFolder,$outputFolder){ $images = $this->getFiles($inputFolder); if(empty($images)){ return false; } foreach($images as $image){ $input = $inputFolder."\\".$image; $output = $outputFolder."\\".$image; print($input."<br>"); print($output."<br>"); $this->compressImg($key,$input,$output); } return true; } /*Compress one image $input and save as $output*/ public function compressImg($key, $input, $output){ $url = "https://api.tinify.com/shrink"; $options = array( "http" => array( "method" => "POST", "header" => array( "Content-type: image/png", "Authorization: Basic " . base64_encode("api:$key") ), "content" => file_get_contents($input) ), "ssl" => array( /* Uncomment below if you have trouble validating our SSL certificate. Download cacert.pem from: http://curl.haxx.se/ca/cacert.pem */ "cafile" => __DIR__ . "/cacert.pem", "verify_peer" => true ) ); $result = fopen($url, "r", false, stream_context_create($options)); if ($result) { /* Compression was successful, retrieve output from Location header. */ foreach ($http_response_header as $header) { if (strtolower(substr($header, 0, 10)) === "location: ") { file_put_contents($output, fopen(substr($header, 10), "rb", false)); } } } else { /* Something went wrong! */ print("Compression failed<br>"); } } //get all files' fullname in $filedir public function getFiles($filedir){ $files = []; $dir = @dir($filedir); while(($file = $dir->read())!= false){ if($file != "." and $file != ".."){ $files[] = $file; } } $dir->close(); return $files; } }
(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
wget ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick-6.5.2-7.tar.gz tar -zxvf ImageMagick-6.5.2-7.tar.gz cd ImageMagick-6.5.2-7/ ./configure make make install #译PHP原生库Imagick wget http://pecl.php.net/get/imagick-2.2.2.tgz tar zxvf imagick-2.2.2.tgz cd imagick-2.2.2/ /usr/local/webserver/php/bin/phpize ./configure --with-php-config=/usr/local/webserver/php/bin/php-config make make install #最后,修改php.ini,加上(去除下面#号) #extension = "imagick.so"
测试用例
//读取pdf页面的第一页 $im = new Imagick('test.pdf'); //设置输出图片的格式 $im->setImageFormat('png'); //输出图片 header('Content-Type:image/png'); echo $im;
2.2、优化前代码
这个代码中的压缩功能,主要依靠line18的 $imagick->cropThumbnailImage($width, $height);
和line20的 $imagick->resizeImage($width, $height, Imagick::FILTER_LANCZOS, 1, true);
实现的压缩。
/** * 缩小图片尺寸. * * @param $image 待处理的二进制图片 * @param $width 处理后图片尺寸的宽度(px) * @param $height 处理后图片尺寸的高度(px) * @param $crop 是否裁剪图片 * * @return 处理好的二进制图片 */ function resize($image, $width, $height, $crop) { $imagick = new \Imagick(); $imagick->readImageBlob($image); $w = $imagick->getImageWidth(); $h = $imagick->getImageHeight(); if ($w > $width || $h > $height) { if ($crop) { $imagick->cropThumbnailImage($width, $height); } else { $imagick->resizeImage($width, $height, \Imagick::FILTER_LANCZOS, 1, true); } } $processed_image = $imagick->getImageBlob(); return $processed_image; }
2.3 优化后代码
/* * User:Zhang He * Time:20150610 * Function:Resize $src image and store as $dst * */ public static function resize($src, $dst, $width=320, $height=320, $crop=false) { $imagick = new \Imagick($src); $w = $imagick->getImageWidth(); $h = $imagick->getImageHeight(); if ($w > $width || $h > $height) { if ($crop) { $imagick->cropThumbnailImage($width, $height); } else { $imagick->resizeImage($width, $height, \Imagick::FILTER_CATROM, 1, true); } } $imagick->setImageFormat('JPEG'); $imagick->setImageCompression(\Imagick::COMPRESSION_JPEG); $a = $imagick->getImageCompressionQuality() * 0.75; if ($a == 0) { $a = 75; } $imagick->setImageCompressionQuality($a); $imagick->stripImage(); $imagick->writeImage($dst); $imagick->clear(); $imagick->destroy(); }
(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
)
生成一个指定大小的缩略图,首先放大或缩小图片,然后裁剪出一个指定的区域从图片中间。示例代码:
<?php /* Read the image */ $im = new imagick( "test.png" ); /* create the thumbnail */ $im->cropThumbnailImage( 80, 80 ); /* Write to a file */ $im->writeImage( "th_80x80_test.png" ); ?>
(3)选择哪个过滤器?
将一个5906*5906的图片压缩至1181*1181所需时间对比:FILTER_POINT took: 0.334532976151 seconds FILTER_BOX took: 0.777871131897 seconds FILTER_TRIANGLE took: 1.3695909977 seconds FILTER_HERMITE took: 1.35866093636 seconds FILTER_HANNING took: 4.88722896576 seconds FILTER_HAMMING took: 4.88665103912 seconds FILTER_BLACKMAN took: 4.89026689529 seconds FILTER_GAUSSIAN took: 1.93553304672 seconds FILTER_QUADRATIC took: 1.93322920799 seconds FILTER_CUBIC took: 2.58396601677 seconds FILTER_CATROM took: 2.58508896828 seconds FILTER_MITCHELL took: 2.58368492126 seconds FILTER_LANCZOS took: 3.74232912064 seconds FILTER_BESSEL took: 4.03305602074 seconds FILTER_SINC took: 4.90098690987 seconds
因此,CATROM在保证压缩效果接近LANCZOS的同时,耗时也比较短。
(4)最简洁代码示例
我找到最简洁的例子是这个:/* Imagick::setImageCompression Imagick::setImageCompressionQuality Imagick::stripImage Imagick::thumbnailImage Imagick::writeImage */ <?php $image = 'image.jpg'; $directory = '/path/to/image'; $image_location = $directory . "/" . $image; $thumb_destination = $directory . "/t" . $image; $compression_type = Imagick::COMPRESSION_JPEG; $im = new Imagick($image_location); $thumbnail = $im->clone; $thumbnail->setImageCompression($compression_type); $thumbnail->setImageCompressionQuality(40); $thumbnail->stripImage(); $thumbnail->thumbnailImage(100,null); $thumbnail->writeImage($thumb_destination); ?>
相关文章推荐
- PHP单例模式例程
- PHP header函数初级接触
- php发送html格式文本邮件的方法
- php简单实现发送带附件的邮件
- laravel Eloquent ORM
- iOS下使用rsa算法与php进行加解密通讯
- thinkphp 相关
- PHP数字前补0的自带函数sprintf 和number_format的用法
- PHP漏洞全解(七)-Session劫持
- Note: No relevant classes found. No output generated.
- PHP array_pad()
- php 下全角逗号和英文逗号的汉字字符串分割成数组
- PHP array_multisort()
- PHP 实现Word,excel等转换pdf
- PHP array_merge_recursive()
- 在win7+wampserver环境下安装composer
- PHP array_merge()
- php动态变量定义及使用
- php中动态变量用法实例
- 关于随机生成订单号的解决方案