前言

因公司文档系统文件较多,图片、pdf、视频、excel等文件共占用磁盘空间,2T左右,鉴于之前系统上传照片时,未对图片大小进行压缩处理,造成服务器内存资源浪费,故需要对系统中的图片进行压缩处理,此次压缩主要是针对系统中2M以上的图片进行压缩处理。

服务器为centos系统,经过查阅资料,常用的图片压缩工具为jpegoptim、optimpng,2款分别针对jpg与png格式的图片进行压缩,在实际压缩之前对这两款工具进行了实际测试。

安装

# 支持处理文件类型:JPG、JPEG
sudo yum install jpegoptim
​
# 支持处理文件类型:PNG, BMP, GIF, PNM or TIFF,这个优化效率太低了,速度奇慢无比
sudo yum install optipng

其中2款工具的具体使用参数如下

JPEGOPTIM
​
名称
       jpegoptim - 用于优化/压缩JPEG/JFIF文件。
概要
       jpegoptim [ options ] [ filenames ]
描述
       pegoptim用于优化/压缩jpeg文件。项目支持无损优化,这是基于对Huffman表的优化。所谓的“有损”优化除了优化之外。可以指定图像质量的上限。
选项
       选项可以是传统的POSIX一个字母选项,也可以是。GNU风格长选项。 POSIX风格选项以一个“-”开头,而GNU的长选项以''--'开头。
       
jpegoptim提供的选项如下:
       
      -d<path>, --dest=<path>
      //设置备选目标目录,以便保存优化。文件(默认是覆盖原始文件)。
      //请注意,不变的文件不会被添加到目标目录。
      //这意味着如果源文件不能被压缩,就不会有文件。在目标路径中创建。
​
      -f, --force
      //强制优化,即使结果大于。原始文件。
​
      -h, --help
     //显示简短的使用信息并退出。
      -m<quality>, --max=<quality>
      //设置最大图像质量因子(禁用无损优化)。mization模式是默认启用的。
      //设置这个选项会降低使用更高版本保存的源文件的质量。而那些已经有较低质量的文件。设置将使用无损优化进行压缩。
​
      -n, --noaction
      //不要真的优化文件,只需打印结果。
​
      -S<size>, --size=<size>
      //尝试优化文件大小(禁用了无损优化mizaiont模式)。目标尺寸指定KB(1 N)或百分比(1% - 99%)的原始文件的大小。
​
      -T<treshold>, --threshold=<treshold>
      //如果压缩增益低于阈值(%),则保持文件不变。传输安全有效值为:0 - 100
​
      -o, --overwrite
      //覆盖目标文件,即使它存在(使用D选项)。
​
      -p, --preserve
      //保存文件修改时间。
​
      -q, --quiet
      //安静模式。
​
      -t, --totals
      //处理完所有文件后打印总计。
​
      -v, --verbose
      //启用详细模式(积极聊天).
​
      --all-normal
      //强制所有输出文件为非逐行扫描。可以用来转换所有输入文件的渐进式JPEG当使用--force选项。
​
      --all-progressive
      //强制所有输出文件都是渐进的。可以将所有输入文件正常(非连续)当使用--force选项的JPEG文件。
​
      --strip-all
      //去除所有(Comment  & Exif)从输出文件删除标记。(注!默认情况下只有Comment  & Exif标记保存,其他一切都是丢弃)
​
      --strip-com
      //从输出文件中删除Comment(COM)标记。
​
      --strip-exif
      //从输出文件中删除标记。
​
      --strip-iptc
      //从输出文件中删除IPTC标记。
    
      --strip-icc
      //将ICC配置文件从输出文件中删除。
​
Bugs:
​
      当使用size选项时,结果文件并不总是精确的请求大小。解决方法是重新运行jpegoptim在同一文件又往往会导致文件大小接近目标。
OPTIPNG命令手册
​
NAME
      OptiPNG−优化便携式网络图形文件
​
SYNOPSIS
      optipng [−? | −h | −help]
      optipng [options...] files...
​
DESCRIPTION
      
      OptiPNG程序将尝试优化PNG文件,即将其大小减小到最小值。失去语义信息。此外,该程序还应执行一套辅助功能。完整性检查、元数据恢复和pixmapto - png转换。
      优化尝试不能保证成功。有效的PNG文件不能被这个程序优化,通常是原封不动的,它们的大小不会增长。用户可以请求重写此默认行为。
​
FILES
      输入文件是用PNG格式(本机格式)或外部格式编码的光栅图像文件。当前支持的外部格式是GIF、BMP、PNM和TIFF。
      OptiPNG处理命令行中给出的每个图像文件如下:
      −如果是PNG格式的图像:
            试图优化给定文件的位置。如果优化是成功的,或者选择−力被激活,其优化的版本替换原来的文件。原始文件备份,如果选择−保持启用。
      −如果图像是一个外部格式:
            创建给定文件的优化PNG版本。输出文件名由原始文件名和PNG扩展名组成。
      现有的文件不会被覆盖,除非该选项启用−clobber
​
OPTIONS
​
  通用选项
      −?, −h, −help //显示选项的完整摘要。
      
      −backup, −keep //对修改后的文件进行备份。
​
      −clobber //覆盖现有的输出和备份文件。在这个选项,如果选择−backup 未启用,覆盖旧的备份文件的删除。
​
      −dir directory //将输出文件写入目录。
​
      −fix //启用错误恢复。此选项对有效的输入文件没有影响。
      //程序将花费大量的精力在不增加输出文件大小的情况下尽可能地恢复尽可能多的数据,但不能保证成功。该程序可能会增加文件的大小,例如,重建丢失的关键数据。在此选项下,完整性应优先于文件大小。
      //当此选项未被使用时,无效的输入文件将被未处理。
​
      −force //强制编写新的输出文件。
      //此选项覆盖程序的决定不写这样的文件,例如当PNG输入数字签名(使用dsig),或当PNG输出变得大于PNG输入。
​
      −log file //将消息记录到文件。出于安全原因,文件必须有扩展名。此选项已被废弃,最终将被删除。使用shell重定向。
​
      −out file //将输出文件写入文件。命令行必须只包含一个输入文件。
​
      −preserve //保存(文件属性的文件访问时间邮票,在人权等)适用。
​
      −quiet, −silent // 在安静的运行模式。
​
      −simulate //运行模拟模式:执行测试,但不创建输出文件。
​
      −v //启用该选项 −verbose and −version.
​
      −verbose  //在详细模式运行。
​
      −version //显示版权,版本和建立信息。
      
      −− //选择开关停止解析。
​
PNG编码和优化选项。
​
      −o level //选择优化级别
      //优化level0enables一组优化操作,需要最少的努力。将不会有任何变化的图像的属性一样,比特深度或颜色的类型,并没有再压缩现有IDAT数据流。
      //优化level1enables单IDAT压缩试验。试验选择的是什么,OptiPNG认为这可能是最有效的。
      //优化level2和更高的使多个IDAT压缩试验;此选项的行为和默认值可能会在不同的程序版本中发生更改。使用选项−H看到有关您的特定版本。
​
      −f filters //选择PNG增量过滤器。
      //过滤器的参数被指定为一个rangeset(例如−F0−5),和默认的过滤器值取决于设置的选项−O.优化水平过滤器的值0, 1, 2,3和4显示静态滤波,和对应的标准PNG过滤代码(无,左,上,平均和Paeth,分别)。滤波值5表明自适应滤波,其作用是通过libpng的定义(3)用optipng。
      
    −full //制作一份关于IDAT的完整报告。这种选择可能会减缓试验的速度。
​
      −i type //选择交错类型(0−1)。
      //如果交错式0被选择,输出图像应非隔行扫描(即progressivescanned)。如果交错式1被选择,输出图像应交错使用adam7方法。默认情况下,输出应具有相同的类型作为输入接口。
​
      −nb //不要应用位深度还原。
      
      −nc //不要使用颜色类型还原。
​
      −np //不应用调色板还原。
​
      −nx //不适用任何无损图像还原:启用选项−nb,-nc控和−−np。
​
      −nz //不记录IDAT数据流
​
      −zc levels //选择IDAT压缩中使用的zlib压缩级别。
​
      −zm levels //选择IDAT压缩中使用的zlib内存级别。
    
      −zs strategies //选择在IDAT压缩中使用的zlib压缩策略。
​
      −zw size //选择zlib窗口大小(32 k,16 k、8 k、4 k,2 k,1 k,512256)中使用IDAT压缩。
​
Editing options
      −snip //从多图像、动画或视频文件中删除一个图像。
      −strip objects //从PNG文件中删除元数据对象。

统计

使用find命令,进行图片数量统计

# 查询大于2M的图片文件
# 查询总数量 :215535个文件
find -type f -size +2M -regex ".*\.\(jpg\|JPG\|jpeg\|JPEG\|png\|PNG\)" | wc -l
​
# 文件大小统计,这个统计
find -type f -size +2M -regex ".*\.\(jpg\|JPG\|jpeg\|JPEG\|png\|PNG\)" | xargs du -ach
​
# 上面文件大小统计的命令不太准确,后面因统计不太准确,所以找到了以下的命令,可以直接计算出文件的大小、文件的数量
# 查询大于2M 的所有图片数量与文件大小    
# 总数量:339586个
# 总大小:1068.79G
# 平均大小:3.2M
find . -size +2048 -regex ".*\.\(jpg\|JPG\|jpeg\|JPEG\|png\|PNG\)" -exec ls -l {} \; |awk 'BEGIN{count=0;size=0;} \
     {count = count + 1; size = size + $5/1024/1024;} \
     END{print "Total count " count; \
       print "Total Size " size/1024 " GB" ; \
       print "Avg Size " size / count "MB"; \
       print "—"}'

测试

1、首先对jpg、jpeg格式的图片进行压缩测试

# 对2M以上文件进行压缩,压缩品质为60,-p为保留原文件修改时间,-t为压缩完成后统计输出压缩率
find . -size +2048 -regex ".*\.\(jpg\|JPG\|jpeg\|JPEG\)" | xargs jpegoptim -m60 -p -t 

以上操作会在原文件基础上进行压缩覆盖,并且保留原文件修改时间,不会覆盖为新的时间,如果有需要是要将压缩后的文件放到新的文件夹中,原文件保留的话可以使用以下命令

# 文件压缩后会输出到new 文件夹,注意需要手动先新建文件夹
find . -size +2048 -regex ".*\.\(jpg\|JPG\|jpeg\|JPEG\)" | xargs jpegoptim -m60 -p -t -d new 

经压缩测试总空间为59G的文件夹(包含不符合压缩条件的文件共计),压缩时间约2小时左右,共释放内存29G

压缩率为74% 左右,其中以1022G为基准进行压缩,具体压缩品质与压缩率对照如下

压缩品质压缩率可释放空间效果
60%74%756G与原图基本无差异
50%77%786G与原图基本无差异
30%83%848G清晰度放大之后有些许的降低
20%86%879G清晰度放大之后有降低
10%90%919G清晰度放大之后有明显差异

2、对png格式进行压缩

# 默认压缩如下,其他参数如上述参数描述,可以视情况进行增加
find -name '*.png' | xargs optipng

经测试,这个压缩速度极慢无比,不知道是不是我使用方法不当,而且压缩率很低,一个10861KB的png图片,压缩之后为10858KB。有人说是因为optipng会对比各种优化方案,选择最优的方案所以比较慢。

鉴于此,且系统中的png图片占相对比较小相对于jpg的1个T左右,总共9个G,故此次不对png图片进行压缩。

3、如果有需要,压缩png图片的话,可以使用ImageMagick 使用这个包,然后使用以下命令进行压缩,压缩率较高,可以压缩任意格式的图片,但是速度相对于jpegoptim有点慢

# ImageMagick
sudo install ImageMagick
# png格式的图片压缩使用optimpng  压缩效率太低了 ,使用ImageMagick测试可行,但是效率一般,150M大小10个文件左右需要35秒左右,不过可以压缩大文件,且不区分文件类型都可以压缩, 如100M以上的jpg、png都可以文件
 find ./ -regex '.*\(png\|PNG\)' -size +2M -exec convert  -quality 60 {} {} \;

注意

测试过程中发现有几点问题需要注意的,此处做一个汇总

1、尽量使用root账号进行压缩,否则原拥有者为root,使用其他账号压缩之后会变更为登录账号,且压缩过程中输出详情信息会提示错误,就是因为无法变更拥有者为root,不过文件可以正常压缩。

2、压缩之前尽量先对文件进行备份,避免出现意向不到的问题

3、测试过程中,曾经对一个119M的jpg文件进行压缩,但是却报错了,开始以为是jpegoptim对于太大的文件压缩不支持,后续使用参数

-v, --verbose //启用详细模式(积极聊天)

发现错误信息为,提示:Not a JPEG file: starts with 0x89 0x50,由此可以发现,这个jpg文件为假的jpg,有可能是该文件上传之前为png或者其他格式,经过手动修改变成了jpg格式,所以造成无法处理,针对此类文件只能进行单独处理了,比如使用上述的ImageMagick进行压缩,可以将119M的文件压缩至7M左右。

总结

因为本身对于Linux系统不太熟悉,所以在实际过程中还是走了不少的弯路的,还在最终提供了完整的解决方案,记录学习。

后续

实际操作过程中发现,使用jpegoptim 后台执行,中间不知道为中断了,而且可能是系统之前对上传的图片进行了重命名,所以造成了大量图片无法进行压缩,报错信息为:Not a JPEG file: starts with 0x89 0x50,综合考虑,切换方案,使用ImageMagick

# 后台执行,为避免报错还要加上这个>/dev/null 2>/dev/null,否则会报nohup: ignoring input and appending output to ‘nohup.out’
nohup find ./ -regex '.*\(jpg\|jpeg\|JPG\|JPEG\)' -size +2M -exec convert  -quality 60 {} {} \; >/dev/null 2>/dev/null &

最终压缩内存800G左右,耗时18小时左右,之前压缩测试时这个ImageMagick速度不快,没想到实操过程中速度可观,且压缩品质也不错。

Logo

更多推荐