zoukankan      html  css  js  c++  java
  • 【转载】图片压缩的一些心得

    原文地址: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

  • 相关阅读:
    day25:接口类和抽象类
    vue1
    How the weather influences your mood?
    机器学习实验方法与原理
    How human activities damage the environment
    Slow food
    Brief Introduction to Esports
    Massive open online course (MOOC)
    Online learning in higher education
    Tensorflow Dataset API
  • 原文地址:https://www.cnblogs.com/ainiaa/p/2003174.html
Copyright © 2011-2022 走看看