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下的全部图片的名字列表;
<?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);
?>
ZH奶酪:PHP图片压缩(TinyPNG在线API)和(使用Imagick扩展)的更多相关文章
- android apk瘦身之 图片压缩 tinypng
参考地址: http://blog.csdn.net/jy692405180/article/details/52409369 http://www.tuicool.com/articles/BraI ...
- ZH奶酪:使用PHP调用REST API
原文:http://yuguo.us/weblog/php-rest-api/ 表征状态转移(英文:REpresentational State Transfer,简称REST)是Roy Fieldi ...
- 使用HTML5的两个api,前端js完成图片压缩
主要用了两个html5的 API,一个file,一个canvas,压缩主要使用cnavas做的,file是读取文件,之后把压缩好的照片放入内存,最后内存转入表单下img.src,随着表单提交. 照片是 ...
- 基于H5+ API手机相册图片压缩上传
// 母函数 function App(){} /** * 图片压缩,默认同比例压缩 * @param {Object} path * pc端传入的路径可以为相对路径,但是在移动端上必须传入的路径是照 ...
- HTML5 CANVAS 实现图片压缩和裁切
原文地址:http://leonshi.com/2015/10/31/html5-canvas-image-compress-crop/?utm_source=tuicool&utm_medi ...
- iOS图片压缩处理
理解概念 首先,我们必须明确图片的压缩其实是两个概念: “压” 是指文件体积变小,但是像素数不变,长宽尺寸不变,那么质量可能下降. “缩” 是指文件的尺寸变小,也就是像素数减少,而长宽尺寸变小,文件体 ...
- UIImage 和 iOS 图片压缩UIImage / UIImageVIew
UIImageView 制作气泡 stretchableImageWithLeftCapWidth http://blog.csdn.net/justinjing0612/article/detail ...
- 好久没发贴了,最近捣鼓了个基于node的图片压缩小网站解析。
看了下,距离上次发帖都是去年10月份的事,忙于工作的我很少跑博客园里面来玩了. 做这个小网站的初衷是 https://tinypng.com/ 这个网站有时候访问很慢,然后自己去研究了下图片压缩. 网 ...
- mui手机图片压缩上传+C#
前台参考网址:http://www.bcty365.com/content-146-3263-1.html <html> <head> <meta charset=&qu ...
随机推荐
- Codeforces Round #355 (Div. 2) D. Vanya and Treasure 分治暴力
D. Vanya and Treasure 题目连接: http://www.codeforces.com/contest/677/problem/D Description Vanya is in ...
- POJ 2356 Find a multiple 抽屉原理
从POJ 2356来体会抽屉原理的妙用= =! 题意: 给你一个n,然后给你n个数,让你输出一个数或者多个数,让这些数的和能够组成n: 先输出一个数,代表有多少个数的和,然后再输出这些数: 题解: 首 ...
- HTML5学习笔记4
10.表单元素表单元素用于获取用户的输入数据form 表示HTML表单属性: action 表示表单提交的页面 method 表示表单提交的请求方式:有POST和GET两种,默认GET(P ...
- js 闭包范式概述
在前几篇文章中我介绍过js的闭包,这一篇主要简单的介绍一下js中闭包的范式. 那么何谓闭包的范式呢? 首先回想一下闭包的概念,闭包是外部函数与函数内部之间通信的桥梁,通过对函数的返回,使得外部的函数能 ...
- Android 上SuperUser获取ROOT权限原理解析
Android 上SuperUser获取ROOT权限原理解析 一. 概述 本文介绍了android中获取root权限的方法以及原理,让大家对android 玩家中常说的“越狱”有一个更深层次的认识. ...
- apple developer D-U-N-S® Number
From:https://developer.apple.com/support/D-U-N-S/ The D-U-N-S Number is a unique nine-digit number t ...
- C#中的IDisposable模式
当谈到垃圾回收,在C#中,托管资源的垃圾回收是通过CLR的Garbage Collection来实现的,Garbage Collection会调用堆栈上对象的析构函数完成对象的释放工作:而对于一些非托 ...
- python接口自动化5-Json数据处理
前言 有些post的请求参数是json格式的,这个前面第二篇post请求里面提到过,需要导入json模块处理. 一般常见的接口返回数据也是json格式的,我们在做判断时候,往往只需要提取其中几个关键的 ...
- 使用sun.misc.BASE64Decoder出错解决方案
Access restriction: The type BASE64Decoder is not accessible due to restriction on required library ...
- 如何读取抓取的wifi包内容
有密码的WIFI,WIFI的密码会生成一个临时会话密钥,这个临时会话密钥可以用来加密会话内容,也就是说.比如你在浏览网页,用有密码的WIFI,连接上以后,浏览的网页流量是加密了的,所以更安全.无密码的 ...