• 【转载】图片压缩的一些心得


    原文地址: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的流量费用,如果我们的图片库越来越大,那将更加给力了。

    原文地址:http://blog.lizhigang.net/archives/228

  • 相关阅读:
    课件的引子
    用nc做网络压力测试
    分布式计算学习笔记
    静态库 .a 转成共享库 .so
    nmon用法
    eclipse debug URLClassPath.getLoader(int) file
    sodu 命令场景分析
    俩孩随笔
    深度学习丨深度学习中GPU和显存分析
    语义分割丨DeepLab系列总结「v1、v2、v3、v3+」
  • 原文地址:https://www.cnblogs.com/ainiaa/p/2003174.html
Copyright © 2020-2023  润新知