1. 选择一个合适的图片处理扩展包。

    • 常见的扩展如GD,imagick,Gmagick。
    • 老古董的GD丢掉吧,效率很低,而且压缩的图片体积很大=。=   imagick是个不错的选择,在PHP的图片处理扩展中表现的很显眼。不管是对jpg或png的静态图片,还是对gif的动态图片,压缩和缩小放大尺寸都非常给力。
    • Gmagic没怎么试过,而GraphicsMagick据说也是相当的给力,但网上很多评论基本上都是对效率的一些评测。
    • 程序的优化,看下三个小组的解决方案和最终最好的解决方案。

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

优化前:

/**
* 缩小图片尺寸.
*
* @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的流量费用,如果我们的图片库越来越大,那将更加给力了。

imagick图片压缩。的更多相关文章

  1. ZH奶酪:PHP图片压缩(TinyPNG在线API)和(使用Imagick扩展)

    1.调用TinyPng网站提供的API 1.1.须知 (1)tinypng的官网:https://tinypng.com/ 不知道国内访问会不会很慢,在Singapore打开这个网站很流畅: (2)A ...

  2. Golang 编写的图片压缩程序,质量、尺寸压缩,批量、单张压缩

    目录: 前序 效果图 简介 全部代码 前序: 接触 golang 不久,一直是边学边做,边总结,深深感到这门语言的魅力,等下要跟大家分享是最近项目 服务端 用到的图片压缩程序,我单独分离了出来,做成了 ...

  3. 三款不错的图片压缩上传插件(webuploader+localResizeIMG4+LUploader)

    涉及到网页图片的交互,少不了图片的压缩上传,相关的插件有很多,相信大家都有用过,这里我就推荐三款,至于好处就仁者见仁喽: 1.名气最高的WebUploader,由Baidu FEX 团队开发,以H5为 ...

  4. 前端构建工具之gulp(一)「图片压缩」

    前端构建工具之gulp(一)「图片压缩」 已经很久没有写过博客了,现下终于事情少了,开始写博吧 今天网站要做一些优化:图片压缩,资源合并等 以前一直使用百度的FIS工具,但是FIS还没有提供图片压缩的 ...

  5. gulp图片压缩

    gulp图片压缩 网页性能优化,通常要处理图片,尤其图片量大的时候,更需要工具来批量处理,这里使用gulp,做个简单总结 image-resize压缩尺寸 var gulp = require('gu ...

  6. Android 图片压缩、照片选择、裁剪,上传、一整套图片解决方案

    1.Android一整套图片解决方案 http://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650820998&idx=1& ...

  7. Java中图片压缩处理

    原文http://cuisuqiang.iteye.com/blog/2045855 整理文档,搜刮出一个Java做图片压缩的代码,稍微整理精简一下做下分享. 首先,要压缩的图片格式不能说动态图片,你 ...

  8. android 图片压缩

    引用:http://104zz.iteye.com/blog/1694762 第一:我们先看下质量压缩方法: private Bitmap compressImage(Bitmap image) { ...

  9. HTML5 CANVAS 实现图片压缩和裁切

    原文地址:http://leonshi.com/2015/10/31/html5-canvas-image-compress-crop/?utm_source=tuicool&utm_medi ...

随机推荐

  1. my-> git使用笔记

    要在本地新建分支test0227并切换到该分支,运行git checkoutout 并加上-b参数,如: git checkout -b test0227 这相当于执行下面这两条命令: git bra ...

  2. asp.net站点从2003服务器迁移到2008服务器出现定义了重复的“system.web.extensions/scripting/scriptResourceHandler”节的问题解决

    解决方法: 1.从4.0降到2.0. 2.直接删除整个节点,如下:

  3. go语言学习之路六:接口详解

    Go语言没有类和继承的概念,但是接口的存在使得它可以实现很多面向对象的特性.接口定义了一些方法,但是这些方法不包含实现的代码.也就是说这些代码没有被实现(抽象的方法).同时接口里面也不包含变量. 看一 ...

  4. C#获取程序所在的目录

    有的时候,我们需要读取程序所在目录下的一些文件,最常见的写法是直接通过".\xxx.file"之类的相对路径来获取文件.虽然这种写法大多数的时候能正确工作,但却又一个很大的隐患:程 ...

  5. 【IntelliJ Idea】idea快速创建maven spring项目

    想试试AOP在spring的web项目上的使用情况,所以想尽快使用idea快速的搭建一个spring的web项目,当然,是maven管理的项目 步骤如下: 1.打开idea 左上角file---> ...

  6. 安全 -- mysql参数化查询,防止Mysql注入

    参数化查询(Parameterized Query 或 Parameterized Statement)是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数(Parameter) ...

  7. css样式大全(整理版)

    字体属性:(font) 大小 {font-size: x-large;}(特大) xx-small;(极小) 一般中文用不到,只要用数值就可以,单位:PX.PD 样式 {font-style: obl ...

  8. lnmp环境网页访问慢排查思路

    1.首先看每个服务器的负载情况 2.若各个服务器负载不高 首先查看是不是负载均衡服务器问题相接访问web服务看是否慢,若也慢则查看是不是访问动态页面慢,创建一个静态页面访问试试,若不慢则是动态页面问题 ...

  9. apue学习笔记(第十四章 高级I/O)

    本章涵盖了从多概念和函数:非阻塞I/O.记录锁.I/O多路转换.异步I/O.readv和writev函数以及存储映射I/O 非阻塞I/O 非阻塞I/O使我们可以发出open.read和write这样的 ...

  10. 生成二维码 加密解密类 TABLE转换成实体、TABLE转换成实体集合(可转换成对象和值类型) COOKIE帮助类 数据类型转换 截取字符串 根据IP获取地点 生成随机字符 UNIX时间转换为DATETIME\DATETIME转换为UNIXTIME 是否包含中文 生成秘钥方式之一 计算某一年 某一周 的起始时间和结束时间

    生成二维码 /// <summary>/// 生成二维码/// </summary>public static class QRcodeUtils{private static ...