本文介绍了如何在Linux系统中使用OptiPNG和Jpegoptim工具对指定目录下的图片进行定时自动无损压缩。首先,确保已安装OptiPNG和Jpegoptim库,并提供了安装命令。接着,编写了一个Bash脚本compress_images.sh
,用于递归查找指定目录下的PNG和JPEG图片,并进行压缩。脚本还支持记录日志和避免重复压缩已处理的图片。文章详细解释了OptiPNG和Jpegoptim的压缩参数及其效果,并通过测试展示了压缩前后的文件大小对比。最后,介绍了如何使用cron
或宝塔面板设置定时任务,以便每天自动执行压缩脚本,从而节省服务器资源并优化图片存储。
确保已经安装了OptiPNG
和Jpegoptim
。如果没有安装,可以使用以下命令进行安装:
sudo apt-get update
sudo apt-get install optipng jpegoptim
看看自己有没有安装的命令:
jpegoptim -V
optipng -V
可以看到小陶已经安装好了。
创建一个Bash脚本,例如compress_images.sh
,并添加以下内容:
(这里小陶决定先用一个tempimage文件夹来进行尝试压缩,测试脚本的效果)
#!/bin/bash
# 定义图片目录
IMAGE_DIR="/path/to/your/images"
# 定义日志文件
LOG_FILE="/var/log/image_compression.log"
# 如果日志文件不存在,则创建它
touch "$LOG_FILE"
# 记录开始时间
echo "开始压缩图片: $(date)" >> "$LOG_FILE"
# 压缩PNG图片(递归查找子目录)
if find "$IMAGE_DIR" -type f -iname "*.png" -print -quit | grep -q .; then
find "$IMAGE_DIR" -type f -iname "*.png" -exec optipng -o7 -quiet {} \; >> "$LOG_FILE" 2>&1
else
echo "未找到PNG图片,跳过压缩。" >> "$LOG_FILE"
fi
# 压缩JPEG图片(递归查找子目录)
if find "$IMAGE_DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -print -quit | grep -q .; then
find "$IMAGE_DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -exec jpegoptim --max=75 --strip-all --quiet {} \; >> "$LOG_FILE" 2>&1
else
echo "未找到JPEG图片,跳过压缩。" >> "$LOG_FILE"
fi
# 记录结束时间
echo "图片压缩完成: $(date)" >> "$LOG_FILE"
调整压缩参数:
PNG图片:
PNG_COMPRESSION_LEVEL
变量的值,例如-o3
或-o7
。OptiPNG
的压缩程度通过-o
参数控制,范围从-o0
(最低压缩)到-o7
(最高压缩)。默认值是-o2
。-o7
通常可以将文件大小减少10%-50%,具体取决于图片内容。JPEG:
JPEG_QUALITY
变量的值,例如--max=85
或--max=95
。Jpegoptim
的压缩程度通过--max=
参数控制,它指定JPEG图片的质量百分比。范围从0
(最低质量,最高压缩)到100
(最高质量,无压缩)。--max=90
通常可以在保持良好质量的同时减少文件大小20%-60%。tips:如果你对图片质量要求较高,建议在压缩前备份原始图片。
OptiPNG
是一种无损压缩工具,它通过优化PNG文件的编码方式来减小文件大小。重复压缩PNG图片时,可能会出现以下情况:
第一次压缩:
OptiPNG
可以显著减小文件大小。后续压缩:
OptiPNG
优化过,再次运行OptiPNG
通常不会进一步减小文件大小。OptiPNG
会检测文件是否已经是最优状态,如果是,则跳过压缩。Jpegoptim
是一种有损或无损压缩工具,具体取决于是否指定了--max=
参数。重复压缩JPEG图片时,可能会出现以下情况:
无损压缩:
--max=
参数,Jpegoptim
会无损地移除JPEG文件中的冗余数据(如元数据)。有损压缩:
--max=
参数(例如--max=90
),Jpegoptim
会重新编码JPEG文件以降低质量。#!/bin/bash
# 定义图片目录
IMAGE_DIR="/path/to/your/images"
# 定义日志文件
LOG_FILE="/var/log/image_compression.log"
# 定义已压缩文件的记录文件
COMPRESSED_FILE="/tmp/compressed_files.txt"
# 如果记录文件不存在,则创建它
touch "$COMPRESSED_FILE"
touch "$LOG_FILE"
# 定义压缩参数
PNG_COMPRESSION_LEVEL="-o7" # OptiPNG压缩级别(-o0到-o7)
JPEG_QUALITY="--max=70" # Jpegoptim图片质量(0到100)
# 记录开始时间
echo "开始压缩图片: $(date)" >> "$LOG_FILE"
# 压缩PNG图片(递归查找子目录)
if find "$IMAGE_DIR" -type f -iname "*.png" -print -quit | grep -q .; then
find "$IMAGE_DIR" -type f -iname "*.png" | while read -r file; do
if [[ -s "$COMPRESSED_FILE" ]] && grep -Fxq "$file" "$COMPRESSED_FILE"; then
echo "跳过已压缩PNG文件: $file" >> "$LOG_FILE"
else
optipng $PNG_COMPRESSION_LEVEL -quiet "$file" >> "$LOG_FILE" 2>&1
echo "$file" >> "$COMPRESSED_FILE"
fi
done
else
echo "未找到PNG图片,跳过压缩。" >> "$LOG_FILE"
fi
# 压缩JPEG图片(递归查找子目录)
if find "$IMAGE_DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -print -quit | grep -q .; then
find "$IMAGE_DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) | while read -r file; do
if [[ -s "$COMPRESSED_FILE" ]] && grep -Fxq "$file" "$COMPRESSED_FILE"; then
echo "跳过已压缩JPEG文件: $file" >> "$LOG_FILE"
else
jpegoptim $JPEG_QUALITY --strip-all --quiet "$file" >> "$LOG_FILE" 2>&1
echo "$file" >> "$COMPRESSED_FILE"
fi
done
else
echo "未找到JPEG图片,跳过压缩。" >> "$LOG_FILE"
fi
# 记录结束时间
echo "图片压缩完成: $(date)" >> "$LOG_FILE"
在服务器的命令窗口输入命令:
cd Bash脚本所在目录
chmod +x compress_images.sh
./compress_images.sh
文件名 | 压缩前 | 压缩后(1次) | 压缩后(2次) |
---|---|---|---|
test8.png | 1.16 MB | 774.76 KB | 774.76 KB |
test7 jpg | 332.44 KB | 331.28 KB | 330.91 KB |
test6.jpg | 271.03 KB | 246.48 KB | 246.48 KB |
test5.jpg | 280.06 KB | 115.23 KB | 115.23 KB |
test4.png | 950.38 KB | 632.35 KB | 632.35 KB |
test3.jpeg | 328.01 KB | 51.72 KB | 51.70 KB |
test2.png | 1.07 MB | 792.11 KB | 792.11 KB |
test1.jpeg | 133.28 KB | 133.27 KB | 133.27 KB |
可以看出:当重复对一个图片进行压缩的话,后续的压缩其实效果也不是很明显。为了节省服务器的压缩计算成本。建议使用记录已压缩文件方式的不重复压缩版本bash脚本!
(1)使用cron
来定时执行脚本。编辑crontab
:
crontab -e
添加以下行来每天凌晨2点执行脚本:
0 2 * * * /path/to/compress_images.sh
cron设置定时任务的相关教程:Linux Crontab 定时任务
(2)宝塔面板shell定时执行sh脚本