2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

大量の画像ファイルをWebPに変換する

Posted at

前提

大前提として大量のjpg/png/bmp/gifの入り混じった画像ファイルがあるのはそうなのだが、以下のソフトを利用する。

実装

シェルスクリプトで書く。

とりあえずお決まり

#!/bin/bash
set -e

libwebpに含まれるgif2webpを用いて、gifをWebPに変換する。
この時、元ファイルと変換後のファイルの小さいほうを残す。

function conv_gif(){
        for arg; do
                FN=`basename "${arg}"`
                FDIR=`dirname "${arg}"`
                OUT=${FN%.*}.webp
                pushd "${FDIR}" >/dev/null 2>&1
                if [ ! -f "${OUT}" ]; then
                        gif2webp -mixed -m 6 -v -o "${OUT}" "${FN}"
                fi
                if [ -f "${OUT}" -a -s "${OUT}" ]; then
                        P_SIZE=`stat -c %s -- "${FN}"`
                        A_SIZE=`stat -c %s -- "${OUT}"`
                        if [ ${P_SIZE} -gt ${A_SIZE} ]; then
                                rm -- "${FN}"
                        else
                                rm -- "${OUT}"
                        fi
                fi
                popd >/dev/null 2>&1
        done
}
export -f conv_gif
find -O3 -type f -iname \*.gif -print0 | parallel -0 --eta -r --nice 10 -q conv_gif

bmpやtiffをとりあえずpngにする。ここで使うのはgm(GraphicsMagick)

function conv_png(){
        for arg; do
                FN=`basename "${arg}"`
                FDIR=`dirname "${arg}"`
                OUT=${FN%.*}.png
                pushd "${FDIR}" >/dev/null 2>&1
                if [ -f "${OUT}" ]; then
                        rm -- "${FN}"
                else
                        gm convert "${FN}" "${OUT}"
                        if [ -f "${OUT}" -a -s "${OUT}" ]; then
                                rm -- "${FN}"
                        fi
                fi
                popd >/dev/null 2>&1
        done
}
export -f conv_png
find -O3 -type f \( -iname \*.bmp -or -iname \*.tif -or -iname \*.tiff \) -print0 | parallel -0 --eta --nice 10 -r -q conv_png
find -empty -delete

jpgやpngをWebPにする。
ここでもやはり、元ファイルと変換後のファイルの小さいほうを残す。
また、一部のjpgがcwebpだと読み取りに失敗するので、失敗した場合は一旦pngに変換してリトライする。

function conv_webp(){
        for arg; do
                FN=`basename "${arg}"`
                FDIR=`dirname "${arg}"`
                OUT=${FN%.*}.webp
                pushd "${FDIR}" >/dev/null 2>&1
                if [ ! -f "${OUT}" ]; then
                        cwebp -m 6 -af -sharp_yuv -quiet -alpha_filter best -o "${OUT}" -- "${FN}"
                fi
                if [ ! -f "${OUT}" ]; then
                        gm convert "${FN}" "${FN%.*}.new.png"
                        P_SIZE=`stat -c %s -- "${FN}"`
                        A_SIZE=`stat -c %s -- "${FN%.*}.new.png"`
                        if [ ${P_SIZE} -gt ${A_SIZE} ]; then
                                rm -- "${FN}"
                                mv "${FN%.*}.new.png" "${FN%.*}.png"
                        else
                                cwebp -m 6 -af -sharp_yuv -quiet -alpha_filter best -o "${OUT}" -- "${FN%.*}.new.png"
                                rm -- "${FN%.*}.new.png"
                        fi
                fi
                if [ -f "${OUT}" -a -s "${OUT}" ]; then
                        P_SIZE=`stat -c %s -- "${FN}"`
                        A_SIZE=`stat -c %s -- "${OUT}"`
                        if [ ${P_SIZE} -gt ${A_SIZE} ]; then
                                rm -- "${FN}"
                        else
                                rm -- "${OUT}"
                        fi
                fi
                popd >/dev/null 2>&1
        done
}
export -f conv_webp
find -O3 -type f \( -iname \*.jpg -or -iname \*.jpeg -or -iname \*.png \) -print0 | parallel -0 --eta --nice 10 -r -q conv_webp
find -empty -delete

pngを最適化する。
当然、元ファイルと変換後のファイルの小さいほうを残す。

function opt_png(){
        for arg; do
                FN=`basename "${arg}"`
                FDIR=`dirname "${arg}"`
                OUT=${FN%.*}.opt.png
                pushd "${FDIR}" >/dev/null 2>&1
                if [ ! -f "${OUT}" ]; then
                        zopflipng -m --filters=01234me --lossy_transparent --lossy_8bit "${FN}" "${OUT}"
                fi
                if [ -f "${OUT}" -a -s "${OUT}" ]; then
                        P_SIZE=`stat -c %s -- "${FN}"`
                        A_SIZE=`stat -c %s -- "${OUT}"`
                        if [ ${P_SIZE} -gt ${A_SIZE} ]; then
                                rm -- "${FN}"
                                mv "${OUT}" "${FN}"
                        else
                                rm -- "${OUT}"
                        fi
                fi
                popd >/dev/null 2>&1
        done
}
export -f opt_png
find -O3 -type f -iname \*.png -print0 | parallel --nice 10 -0 --eta -r -q opt_png
find -empty -delete
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?