• 图片优化调研之实践篇


    前言

    之前的文章——图片优化调研之理论篇——主要以理论的东西为主。正确选择合适的图片格式——不管你用Fireworks还是Photoshop,可用预览功能多去尝试,选择size最小的且确保质量(其场景与PM商定)的图片。另一个方面,就是无损压缩。本篇文章主要针对自动无损压缩,具体再啰嗦一下如何实现。

    实践

    1.pngout客户端实现图片批量无损压缩

    pngout官网提供一个windows平台客户端版本——http://www.ardfry.com/pngoutwin/ 简单介绍它怎么用——

    1.1 设置压缩图片输出路径

    1.2 选择源图文件夹

    这里仅仅针对批量压缩——

    1.3 看结果

    这里对common模块(随意举例)进行例子解析——

     

    当压缩图片的格式选择gif的时候(仅仅针对gif格式的图片进行压缩),会看到——

    所有的gif图片均转换为png格式图片,再进行无损压缩,整体压缩之后的结果——

    出现一个问题,本来loading.gif是多帧动画,却被压缩成了单帧png,不符合预期。因此,这里的整体替换(gif-->png)存在一定风险,要确保排除动画gif的压缩。

    在这里,就不介绍将jpg转换为png的过程了(同gif),不建议这样去做,以免造成大量失真。

    在来看看它的压缩率,会看到批量压缩节省的字节数——

    自然就能算出整体压缩率了。

    2.smushit

    《高性能网站建设进阶指南》这本书的作者提供的服务http://www.smushit.com/ysmush.it/ 这里使用node-smushit模块实现批量压缩——

      1 var minifier = require('node-smushit');
      2 var log4js = require('log4js');
      3 var logger = log4js.getLogger();
      4 
      5 var util = (function() {
      6     var src_total_size = 0;     // 记录输入图片总大小
      7     var dest_total_size = 0;    // 记录输出图片总大小
      8     var total_percent;          // 记录总的压缩率
      9 
     10     var total = 0;              // 图片总个数
     11     var saving = 0;             // 需要压缩的图片总个数
     12 
     13     // 递增图片总个数
     14     var increaseTotal = function() {
     15         total = total + 1;
     16     };
     17 
     18     // 获取图片总个数
     19     var getTotal = function() {
     20         return total;
     21     };
     22 
     23     // 递增需要压缩的图片总个数
     24     var increaseSaving = function() {
     25         saving = saving + 1;
     26     };
     27 
     28     // 获取需要压缩的图片总个数
     29     var getSaving = function() {
     30         return saving;
     31     };
     32 
     33     // 递增输入图片大小
     34     var increaseSrcTotalSize = function(itemSize) {
     35         src_total_size = src_total_size + itemSize;
     36     };
     37 
     38     // 获取输入图片总大小
     39     var getSrcTotalSize = function() {
     40         return src_total_size;
     41     };
     42 
     43     // 递增输出图片总大小
     44     var increaseDestTotalSize = function(itemSize) {
     45         dest_total_size = dest_total_size + itemSize;
     46     };
     47 
     48     // 获取输出图片总大小
     49     var getDestTotalSize = function() {
     50         return dest_total_size;
     51     };
     52 
     53     // 计算压缩率
     54     var computeTotalPercent = function() {
     55         total_percent = ((src_total_size - dest_total_size) / src_total_size * 100).toFixed(2) + '%';
     56     };
     57 
     58     // 获取压缩率
     59     var getTotalPercent = function() {
     60         return total_percent;
     61     };
     62 
     63     // 压缩图片与原图片的大小差值,即节省了多少字节
     64     var getReduce = function() {
     65         return src_total_size - dest_total_size;
     66     };
     67 
     68     return {
     69         getTotal: getTotal,
     70         getSaving: getSaving,
     71         getSrcTotalSize: getSrcTotalSize,
     72         getDestTotalSize: getDestTotalSize,
     73         getTotalPercent: getTotalPercent,
     74         increaseTotal: increaseTotal,
     75         increaseSaving: increaseSaving,
     76         increaseSrcTotalSize: increaseSrcTotalSize,
     77         increaseDestTotalSize: increaseDestTotalSize,
     78         computeTotalPercent: computeTotalPercent,
     79         getReduce: getReduce
     80     };
     81 })();
     82 
     83 // 打印日志
     84 var printResult = function() {
     85     logger.info('图片总个数:' + util.getTotal());
     86     logger.info('无损压缩图片总个数:' + util.getSaving());
     87 
     88     logger.info('输入需要压缩的图片总大小:' + util.getSrcTotalSize() + ' Bytes');
     89     logger.info('输出经过压缩的图片总大小:' + util.getDestTotalSize() + ' Bytes');
     90     logger.info('-------------共节省大小:' + util.getReduce() + ' Bytes');
     91     logger.info('压缩率(相对输入图片总大小):' + util.getTotalPercent());
     92 };
     93 
     94 // 这里可以指定多个图片文件夹目录,用数组表示
     95 minifier.smushit(['./static/images/', './widget/'], {
     96 
     97     // 循环遍历文件夹及其子目录中的图片设置
     98     // true: 遍历循环
     99     // false: 非遍历循环
    100     recursive: true,
    101 
    102     // 每张图片开始压缩
    103     onItemStart: function(item) {
    104         // 这里的item是每张输入图片的源地址
    105     },
    106 
    107     // 每张图片完成压缩
    108     onItemComplete: function(e, item, response) {
    109         /**
    110          * response的格式——
    111          * {
    112          *      src: '',
    113          *      src_size: ,
    114          *      dest: '',
    115          *      dest_size: ,
    116          *      percent: ,
    117          *      id: ''
    118          * }
    119          */
    120 
    121         // 过滤掉svn目录中的文件
    122         if (/.svn/g.test(response.src) === false) {
    123             util.increaseTotal();
    124 
    125             /*
    126              * 注意:
    127              * 当检测到某些图片已经无法压缩或者已经经过压缩,此时response.src_size的值是undefined
    128              * 因此在这儿加入一层过滤,针对可以压缩的图片进行统计
    129              */
    130             if (response.src_size && response.dest_size) {
    131                 util.increaseSaving();
    132                 util.increaseSrcTotalSize(response.src_size);
    133                 util.increaseDestTotalSize(response.dest_size);
    134             }
    135         }
    136 
    137     },
    138 
    139     // 所有图片完成压缩
    140     // 这里的reports变量记录所有图片的源地址、源大小、目标地址、目标大小、压缩率等信息的列表
    141     onComplete: function(reports) {
    142 
    143         // 统计压缩率
    144         util.computeTotalPercent();
    145 
    146         // 打印统计日志
    147         printResult();
    148     }
    149 });

    可以看到结果——

    3. 其他实现方案

    不管用node或者php或者shell,整体的实现思路均是循环遍历图片,然后使用合适的命令行工具实现无损压缩。在这儿就不继续说了。

  • 相关阅读:
    齐次和线性
    数组指针/指针数组
    坐标转换矩阵
    【转】GMM与K-means聚类效果实战
    利用虚函数实现多态的方式:动态绑定
    类型限定符volatile
    《剑指offer》查找二维数组内元素 c++
    windows下使用命令行编译、链接C++源文件
    关于该博客的美化
    vimium快捷键修改
  • 原文地址:https://www.cnblogs.com/jinguangguo/p/4054952.html
Copyright © 2020-2023  润新知