轉換列表檔案內的JPG/PNG/GIF圖片為WebP, 以parallel工具來同時多工處理為例

在 Linux 下, parallel 工具程式可多工處理工作, 我有一堆圖片要分時段處理, 把它轉成 WebP 圖片, 心想可以用定時工作來處理, 不過 cwebp 程式轉換 WebP 圖片不是飛快, 於是產生了改寫此 Shell Script 來成為多工處理

以下為範例
#!/bin/bash

convertwebp() {
filename="$1"
extension="${filename##*.}"
case "$extension" in
jpg) cwebp -q 85 "$filename" -o "$filename.webp"
echo "$filename.webp" >> /var/log/result.log
;;
gif) gif2webp -q 85 "$filename" -o "$filename.webp"
echo "$filename.webp" >> /var/log/result.log
;;
png) cwebp -q 85 "$filename" -o "$filename.webp"
echo "$filename.webp" >> /var/result.log
;;
esac
}
export -f convertwebp

imagedir="images"
startdate=$(date -d yesterday "+%Y-%m-%d")
enddate=$(date -d today "+%Y-%m-%d")

if [ -d "/mnt/localstorage/$imagedir" ]; then
find /mnt/localstorage/$imagedir -type f -newermt $startdate ! -newermt $enddate > /var/log/convert.log
fi

if [ -f "/var/log/convert.log" ]; then
parallel convertwebp :::: /var/log/convert.log
fi

if [ -f "/var/log/result.log" ]; then
cat /var/log/result.log | gsutil -m -h "Content-Type:image/webp" cp -I gs://googlecloudstorage/$imagedir/
fi

rm /var/log/convert.log
rm /var/log/result.log

echo -e -n "Done!\n"


convertwebp() 函數用於處理圖片轉換為 WebP 格式, 依照副檔名使用不同的轉換程式(cwebp或gif2webp)

find /mnt/localstorage/$imagedir -type f -newermt $startdate ! -newermt $enddate > /var/log/convert.log 尋找我要的時間區間內的檔案, 符合的檔名匯出到 /var/log/convert.log 檔案

parallel convertwebp :::: /var/log/convert.log 用 parallel 讀取 /var/log/convert.log, 將裡面搜集的檔案名稱用 convertwebp 函數來處理

cat /var/log/result.log | gsutil -m -h "Content-Type:image/webp" cp -I gs://googlecloudstorage/$imagedir/ 完成轉換的檔案, 把它存到 Google Cloud Storage 的 Bucket: googlecloudstorage, 並位於 $imagedir 變數所設定的目錄
發現到部分圖片無法被轉換, 用 Imagemagick 檢查圖片, 原來是 CMYK 色彩空間, cwebp 無法轉換非 sRGB 圖片, 於是再修正 script 的 convertwebp 函數為
convertwebp() {

filename="$1"
extension="${filename##*.}"
colorspace=$(identify ${filename} | awk '{print $6}')

if [ $colorspace = "CMYK" ]; then
echo -e -n "Image is CMYK color space, convert to sRGB...\n"
convert -colorspace RGB "$filename" "$filename"
fi

case "$extension" in
jpg) cwebp -q 85 "$filename" -o "$filename.webp"
echo "$filename.webp" >> /var/result.log
;;
gif) gif2webp -q 85 "$filename" -o "$filename.webp"
echo "$filename.webp" >> /var/result.log
;;
png) cwebp -q 85 "$filename" -o "$filename.webp"
echo "$filename.webp" >> /var/result.log
;;
esac
}
export -f convertwebp

利用 identify 先檢查是否為 CMYK 色彩空間, 是的話則用 convert 轉為 RGB 色彩空間, 這樣 cwebp 就工作正常了
突然想到如果正好排程時間內圖片過多處理不完, 下個排程時間來臨, 那麼log檔裡的紀錄會被改寫, 需要用個方法來區別工作, 最簡單就是用Process ID

首先處理convertwebp函數, 在parallel執行時帶入pid
convertwebp() {
local pid="$1"
filename="$2"
extension="${filename##*.}"
case "$extension" in
jpg) cwebp -q 85 "$filename" -o "$filename.webp"
echo "$filename.webp" >> /var/log/result-$pid.log
;;
gif) gif2webp -q 85 "$filename" -o "$filename.webp"
echo "$filename.webp" >> /var/log/result-$pid.log
;;
png) cwebp -q 85 "$filename" -o "$filename.webp"
echo "$filename.webp" >> /var/result-$pid.log
;;
esac
}
export -f convertwebp


全域變數加個pid
pid=$$
imagedir="images"
startdate=$(date -d yesterday "+%Y-%m-%d")
enddate=$(date -d today "+%Y-%m-%d")

如果startdate, enddate時間區間縮小, 很容易碰上log覆寫問題, 所以需要pid區別

呼叫parallel改為
parallel convertwebp $pid :::: /var/log/convert-$pid.log


當然所有log檔都加上pid來識別, 完整的script如下
#!/bin/bash

convertwebp() {
local pid="$1"
filename="$2"
extension="${filename##*.}"
case "$extension" in
jpg) cwebp -q 85 "$filename" -o "$filename.webp"
echo "$filename.webp" >> /var/log/result-$pid.log
;;
gif) gif2webp -q 85 "$filename" -o "$filename.webp"
echo "$filename.webp" >> /var/log/result-$pid.log
;;
png) cwebp -q 85 "$filename" -o "$filename.webp"
echo "$filename.webp" >> /var/result-$pid.log
;;
esac
}
export -f convertwebp

pid=$$
imagedir="images"
startdate=$(date -d yesterday "+%Y-%m-%d")
enddate=$(date -d today "+%Y-%m-%d")

if [ -d "/mnt/localstorage/$imagedir" ]; then
find /mnt/localstorage/$imagedir -type f -newermt $startdate ! -newermt $enddate > /var/log/convert-$pid.log
fi

if [ -f "/var/log/convert-$pid.log" ]; then
parallel convertwebp $pid :::: /var/log/convert-$pid.log
fi

if [ -f "/var/log/result-$pid.log" ]; then
cat /var/log/result-$pid.log | gsutil -m -h "Content-Type:image/webp" cp -I gs://googlecloudstorage/$imagedir/
fi

rm /var/log/convert-$pid.log
rm /var/log/result-$pid.log

echo -e -n "Done!\n"
文章分享
評分
評分
複製連結

今日熱門文章 網友點擊推薦!