add option for jpeg quality
[anondcim.git] / anondcim
1 #!/bin/dash
2
3 # anondcim
4 # forked from http://code.sotun.de/git/anondcim/
5 #
6 # copyright 2012-2014 Jan Huwald, Felix Kästner (fpunktk)
7 #
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21 err() {
22     echo "$*" >&2
23 }
24
25 die() {
26     err "$*"
27     exit 1
28 }
29
30 rand() {
31     # random number between 0 and $1 - 1
32     # read from urandom, sh interpretes numbers with leading 0 wrong, so prepend $1 which doesn't change the result
33     echo $(( $1$(tr -dc "0-9" < /dev/urandom | head -c $((${#1} + 2))) % $1 ))
34 }
35
36 type convert >/dev/null 2>&1 || die "ImageMagick (convert, identify) is not installed"
37 type jhead 1>/dev/null 2>&1 || type exiftool 1>/dev/null 2>&1 || die "jhead or exiftool has to be installed"
38
39 # set default values
40 file_prefix=""
41 dst_size="1920"
42 dst_dir="--same--"
43 jpg_quality="75"
44
45 [ $# -gt 0 ] || die "Usage: $0 [-p image_file_prefix] [-s destination_size (absolute or percentage, default: $dst_size)] [-d destination_directory] [-q destination_jpg_quality (default: $jpg_quality)] imagefile(s)"
46
47 while getopts ':p:s:d:q:' OPTION
48 do
49     case $OPTION in
50         "p")
51             file_prefix="${OPTARG}_"
52         ;;
53         "s")
54             dst_size="$OPTARG"
55         ;;
56         "d")
57             dst_dir="${OPTARG%/}/" # enforce a trailing "/"
58             [ -d "$dst_dir" ] || die "destination directory \"$dst_dir\" does not exist"
59         ;;
60         "q")
61             jpg_quality="$OPTARG"
62         ;;
63         *)
64             err "not recognised: OPTION=$OPTION, OPTARG=$OPTARG"
65         ;;
66     esac
67 done
68 shift $(($OPTIND - 1))
69
70 cur=1
71 total=$#
72 addend=1
73
74 for fn in "$@"
75 do
76     [ -f "$fn" ] || { err "source \"$fn\" does not exist and is skipped"; continue; }
77     #
78     if [ "$dst_dir" = "--same--" ]
79     then
80         # use the directory of the source file
81         dst="$(dirname "$fn")/"
82     else
83         dst="$dst_dir"
84     fi
85     #
86     # always use a padded number as destination filename suffix
87     dst_jpg="$dst$file_prefix$(echo -n "0000000000$cur" | tail -c ${#total}).jpg"
88     while [ -e "$dst_jpg" ] && [ $addend -lt 1000 ]
89     do
90         dst_jpg="$dst$file_prefix$(echo -n "0000000000$(($cur + $addend))" | tail -c ${#total}).jpg"
91         addend=$((addend + 1))
92     done
93     [ -e "$dst_jpg" ] && { err "destination \"$dst_jpg\" for source \"$fn\" already exists, anonymization is skipped"; continue; }
94     #
95     echo "anonymizing \"$fn\" to \"$dst_jpg\" ($cur/$total)"
96     #
97     read w h << EOF
98 $(identify -format '%w %h' "$fn")
99 EOF
100     #
101     # resize and distort
102     if [ $w -ge 100 ] && [ $h -ge 100 ]
103     then
104         if [ $w -ge 1000 ]; then dw=$(($w / 100)); else dw=10; fi
105         if [ $h -ge 1000 ]; then dh=$(($h / 100)); else dh=10; fi
106         #
107         w=$(($w - 1))
108         h=$(($h - 1))
109         #
110         convert "$fn" \
111             -colorspace RGB \
112             -distort Perspective "$(rand $dw) $(rand $dh) 0 0, $(($w - $(rand $dw))) $(rand $dh) $w 0, $(rand $dw) $(($h - $(rand $dh))) 0 $h, $(($w - $(rand $dw))) $(($h - $(rand $dh))) $w $h" \
113             -filter gaussian -define filter:support=5 -define filter:sigma=0.5 \
114             -attenuate 2 +noise Uniform \
115             -resize "$dst_size" \
116             -colorspace sRGB \
117             -quality "$jpg_quality" \
118             "$dst_jpg"
119     else
120         err "image is too small to be distorted and will just be filtered and resized"
121         convert "$fn" \
122             -colorspace RGB \
123             -filter gaussian -define filter:support=5 -define filter:sigma=0.5 \
124             -attenuate 2 +noise Uniform \
125             -resize "$dst_size" \
126             -colorspace sRGB \
127             -quality "$jpg_quality" \
128             "$dst_jpg"
129     fi
130     #
131     # remove metadata
132     if [ -x "$(which jhead)" ]
133     then
134         jhead -purejpg -q "$dst_jpg" || err "removing meta-data with jhead failed"
135     fi
136     if [ -x "$(which exiftool)" ]
137     then
138         exiftool -quiet -overwrite_original -all= "$dst_jpg" || err "removing meta-data with exiftool failed"
139     fi
140     #
141     cur=$(($cur + 1))
142 done
143