`
zhangchibang
  • 浏览: 338935 次
社区版块
存档分类
最新评论

图片压缩的一些心得

    博客分类:
  • PHP
阅读更多

http://blog.lizhigang.net/archives/228

 

这次乐高的题目是如何提高图片的压缩率。帮助公司省流量的费用。

整个过程持续一周。最终的结果相当让人满意,压缩率比之前提高了67.5%,为公司每个月省下至少2W多RMB的流量费用=。=

而且这次的研究也让我对图片的压缩有了一定的心得。

马上分享一下:

  1. 选择一个合适的图片处理扩展包。
    • 常见的扩展如GD,imagick,Gmagick。
    • 老古董的GD丢掉吧,效率很低,而且压缩的图片体积很大=。=   imagick是个不错的选择,在PHP的图片处理扩展中表现的很显眼。不管是对jpg或png的静态图片,还是对gif的动态图片,压缩和缩小放大尺寸都非常给力。
    • Gmagic没怎么试过,而GraphicsMagick据说也是相当的给力,但网上很多评论基本上都是对效率的一些评测。感觉压缩上面不太给力,详细的描述可参看老王的博客http://hi.baidu.com/thinkinginlamp/blog/item/4b61e9241f08820f4c088d95.html
  2. 程序的优化,看下三个小组的解决方案和最终最好的解决方案。

大家对加水印这块无异议,仅在压缩上面做了文章,我只贴这里的代码。

优化前:

/**
* 缩小图片尺寸.
*
* @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;
}

第一小组:

function resize($image, $width, $height, $crop) {

$im = new Imagick();

$im->readImageBlob($image);

$input_width = $width;

$input_height = $height;

$src_width = $im->getImageWidth();

$src_height = $im->getImageHeight();

$width_rate = $src_width/$width;

$height_rate = $src_height/$height;

if($width_rate>1||$height_rate>1){

if($crop){

if($width_rate>$height_rate){

$width = $src_width/$height_rate;

}else{

$height = $src_height/$width_rate;

}

}else{

if($width_rate>$height_rate){

$height = $src_height/$width_rate;

}else{

$width = $src_width/$height_rate;

}

}

$im->resizeImage($width, $height, Imagick::FILTER_CATROM, 1, false);

if($crop){

if($width>$input_width){

$im->cropImage ( $input_width , $height , ($width-$input_width)/2 , 0 );

}elseif($height>$input_height){

$im->cropImage ( $width , $input_height , 0 , ($height-$input_height)/2 );

}

}

}

$im->setImageCompression(Imagick::COMPRESSION_JPEG);

$im->setImageCompressionQuality(75);

$im->stripImage();

$im->setImageFormat(‘JPEG’);

$blob = $im->getImageBlob();

$im->clear();

$im->destroy();

return $blob;

}

第二小组:

function resize($image,$width,$height,$crop) {

$imagick = new Imagick();

$imagick->readImageBlob($image);

$imagick->setImageCompression($compression_type);

$imagick->setImageCompressionQuality(80);

if($crop) {

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

}else{

$imagick->resizeImage($width, $height, Imagick::FILTER_CATROM, 1, true);

}

$imagick->stripImage();

$processed_image = $imagick->getImageBlob();

return $processed_image;

}

第三小组:

function resize($image, $width, $height, $crop) {

$imagick = new Imagick();

$imagick->readImageBlob($image);

if ($crop) {

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

} else {

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

}

$imagick->setImageFormat(‘JPEG’);

$imagick->setImageCompression(Imagick::COMPRESSION_JPEG);

$a = $imagick->getImageCompressionQuality() * 0.75;

if ($a == 0) $a = 75;

$imagick->setImageCompressionQuality($a);

$geo = $imagick->getImageGeometry();

$imagick->ThumbnailImage($geo['width'], $geo['height']);

$imagick->stripImage();

$blob = $imagick->getImageBlob();

$imagick->clear();

$imagick->destroy();

return $blob;

}

最终解决方案:

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_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();

$blob = $imagick->getImageBlob();

$imagick->clear();

$imagick->destroy();

return $blob;

}

看下成绩:

对300张生产环境下抽取的原始图片进行测试,结果如下:

  • 示例代码
    29,220,912 (28,536KB)
  • 1组
    11,282,151 (11,018KB) 比示例代码节省: 61.39%
  • 2组
    16,281,139 (15,900KB) 比示例代码节省44.28%
  • 3组
    10,531,926 (10,285KB) 比示例代码节省63.96%

性能方面都符合要求。除了第3组比示例代码慢5%左右,其他两组都比示例代码更快(1组约快15%,2组约快6%)
2组提交太慢太快,有一处遗漏,其实可以简单提高压缩比到58%左右

之后,综合3组的代码,弄了个best版本,测试结果为,

  • best
    9,626,986 (9,401KB) 比示例代码节省: 67.05%

总结 :

1、压缩率尽可能的小,这个要和业务部门商量,找到一个平衡点。(请注意best方法设置品质方法使用获取到当前图片的压缩率然后再取75%,如果当前图片压缩率为60%,如果使用$imagick->setImageCompressionQuality(80)方法将使图片压缩率提高至80%,这会使图片变大!!!)

2、一定要移除图片的exif信息!!!!  这部分内容详情请查看 http://baike.baidu.com/view/22006.htm

3、压缩尺寸使用Imagick::FILTER_CATROM方法对速度有一定的提升,图片本身的品质没有大的变化。

4、$imagick->setImageFormat(‘JPEG’)也很给力。

5、简单算了一下,这几行代码每个月给我们公司省至少2W RMB的流量费用,如果我们的图片库越来越大,那将更加给力了。

分享到:
评论

相关推荐

    奇异值分解实现图片压缩代码【三个代码+一个实验报告】

    实验报告介绍了奇异值分解在彩色图片压缩中的应用研究。详细解释了奇异值分解的原理,通过分解任意矩阵为三个部分的乘积来实现数据压缩。其次,提供了奇异值分解的代码实现过程,展示了对彩色图片进行压缩的结果。...

    html5 canvas移动浏览器上实现图片压缩上传

    而每次都上传原始大小的图片(后台处理压缩)十分影响用户体验,所以研究了一下通过canvas压缩图片并上传的方法,以下是整理的一些思路和心得: 一、<input type="file">获取本地图片,并将图片绘制到画布中。...

    页面细节处理心得

    一个页面的细节,从重构的角度去看,页面的精细度,代码的可读性、扩展性,为下游服务的代码注释,交互接口样式的书写,代码的压缩,图片的优化等都可以归为细节处理。一个页面的细节,从重构的角度去看,页面的精细...

    vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理

     图片的上传之前都是用的插件(ajaxupload),或者传统上传图片的方式,各有利弊:插件的问题是依赖jq并且会使系统比较臃肿,还有传统的web开发模式 前后端偶尔在一起及对用户体验要求低,现在公司采用webpack+vue+...

    asp.net知识库

    鼠标放在一个连接上,会显示图片(类似tooltip) 使用microsoft.web.ui.webcontrols的TabStrip与IFame组件,达到页的切换效果 HttpModule 实现 ASP.Net (*.aspx) 中文简繁体的自动转换,不用修改原有的任何代码,直接部署...

    java项目之计算机网络实验课程教学网站完整源码(ssm+mysql+jsp).zip

    管理员端: (1)可以按班级批量添加学生、批量删除学生...(3)上传实验报告(源文件或压缩文件、文本、图片) (4)查看自己的实验报告得分 所需开发环境: 开发语言:Java 框架:ssm JDK版本:JDK1.8 服务器:

    java毕业设计之计算机网络实验课程教学网站源码(ssm后端+mysql+前端+说明文档).zip

    (3)上传实验报告(源文件或压缩文件、文本、图片) (4)查看自己的实验报告得分 所需开发环境: 开发语言:Java 框架:ssm JDK版本:JDK1.8 服务器:tomcat7+ 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发...

    java毕业设计之计算机网络实验课程教学网站(ssm前后端完整源码).zip

    (3)上传实验报告(源文件或压缩文件、文本、图片) (4)查看自己的实验报告得分 所需开发环境: 开发语言:Java 框架:ssm JDK版本:JDK1.8 服务器:tomcat7+ 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发...

    SDWebImage_Comment:SDWebImage源码解读下载,缓存,加载等机制详细讲解,附带注释代码-源码下载

    在iOS项目常用的框架中, 是不可少的,相信大...后台图片解码,转换及压缩; 同一个URL不会重复下载; 无限的URL不会被无限重试; 支持GIF动画及WebP格式; 开启子线程进行耗时操作,不双重主线程; 使用GCD和ARC ; SDWebI

    电子教案管理系统 v2.2 免费试用版.rar

    8、在线教师可以对其它或自己的教案进行评论和写教学心得。 10、显示用户列表(待开发中)、教案总数、浏览总数、注册用户总数等统计信息。 11.支持教案打印功能,单独打印页面方便教案打印教案。12.提供学校调查及...

    个人信息管理软件

    6、方便地建立工作日志资料,方便记录每天的工作生活中的心得体会,是你在经验在不断积累中进步。 7、功能强大的计划任务管理 (1)方便地记录工作计划,对任务完成情况进行跟踪,方便地按年、季、月、...

    电子教案管理系统ASP源程序

    8、在线教师可以对其它或自己的教案进行评论和写教学心得。 10、显示用户列表(待开发中)、教案总数、浏览总数、注册用户总数等统计信息。 11.支持教案打印功能,单独打印页面方便教案打印教案。12.提供学校调查及...

    MATLAB源代码MATLAB源码大集合220MB上千个源码文件.zip

    实验心得总结.rar 拉格朗日插值 MATLAB源程序代码.rar 指纹识别的matlab源码.rar 指纹识别的matlab源码.zip 掌握和精通matlab之gui设计.rar 数字信号处理. 理论、算法与实现(胡广书)的MATLAB程序.rar 文字图像识别...

    MATLAB编程源代码文件大全集合【约1000+】

    实验心得总结.rar 拉格朗日插值 MATLAB源程序代码.rar 指纹识别的matlab源码.rar 指纹识别的matlab源码.zip 掌握和精通matlab之gui设计.rar 数字信号处理. 理论、算法与实现(胡广书)的MATLAB程序.rar 文字图像识别...

    针式PinPKM-V201506(免费无使用限制)

    知识库支持文档数:>3万个文档,类型包括:Word、PDF、PPT、图片、安装文件、压缩文件等 搜索支持:文件名瞬间搜索、Word\PDF等文档内容的全文快速搜索 归类方法:分类、标签、多个文档关联、公式等 可运行于:XP、...

    PinPKM-V201525(官网发布的最后一个免费无使用限制版本)

    知识库支持文档数:>3万个文档,类型包括:Word、PDF、PPT、图片、安装文件、压缩文件等 搜索支持:文件名瞬间搜索、Word\PDF等文档内容的全文快速搜索 归类方法:分类、标签、多个文档关联、公式等 可运行于:XP、...

Global site tag (gtag.js) - Google Analytics