Очень часто встречается задача сохранения в компактном виде «смешанный» скана с качеством, аналогичным качеству «сканированный» windows-программы DjvuSolo (в «смешанном» виде, а не черно-белом).
Данная задача решается с помощью bash+imagemagick+djvulibre.
В imagemagick по этапам:
1) Выделить контуры (независимо от цвета) (будущий Sjbz);
2) Создать уменьшенную (1:4) цветовую маску для контуров (будущий FG44);
3) Создать уменьшенную (1:2) версию фона (будущий BG44);
*) Для улучшения сжатия области не попадающие в цветовую маску и фон заполняются средним цветом.
В djvulibre каждый из перечисленных элементов кодируется отдельно с помощью cjb2 и c44, после чего элементы объединяются.
$ cat djvu-colors-v4.sh
#!/bin/bash
if [ -z "$1" ]
then
echo "USAGE: bash $0 images [dpi] [%threshold]"
exit 1
else
src="$1"
fi
if [ -z "$2" ]
then
tdpi="300"
else
tdpi="$2"
fi
if [ -z "$3" ]
then
tthr="50"
else
tthr="$3"
fi
ttmp="/tmp/djvu-colors-$$"
tdim=`identify -verbose "$src" | grep "Geometry:" | awk '{ print $2 }' | awk -F"+" '{ print $1 }'`
convert -verbose -filter Gaussian -resize 50% -blur 0x10 -resize 200% "$src" "$ttmp.b.ppm"
convert -verbose -resize 1x1! -resize "$tdim"! "$src" "$ttmp.c.ppm"
composite -verbose -compose Minus "$ttmp.b.ppm" "$src" "$ttmp.d.ppm"
rm -f "$ttmp.b.ppm"
convert -verbose -negate -level 5%,95% -equalize "$ttmp.d.ppm" "$ttmp.l.ppm"
rm -f "$ttmp.d.ppm"
convert -verbose -threshold "$tthr"% -blur 2 -threshold 50% "$ttmp.l.ppm" "$ttmp.m.pbm"
convert -verbose -negate "$ttmp.m.pbm" "$ttmp.n.pbm"
composite -verbose -compose plus "$ttmp.m.pbm" "$src" "$ttmp.o.ppm"
composite -verbose -compose plus "$ttmp.n.pbm" "$src" "$ttmp.p.ppm"
composite -verbose -compose plus "$ttmp.n.pbm" "$ttmp.c.ppm" "$ttmp.q.ppm"
composite -verbose -compose multiply "$ttmp.o.ppm" "$ttmp.q.ppm" "$ttmp.r.ppm"
convert -verbose "$ttmp.r.ppm" -filter Gaussian -resize 25% "$ttmp.s.ppm"
rm -f "$ttmp.l.ppm"
rm -f "$ttmp.n.pbm"
rm -f "$ttmp.o.ppm"
rm -f "$ttmp.q.ppm"
rm -f "$ttmp.r.ppm"
composite -verbose -compose plus "$ttmp.m.pbm" "$ttmp.c.ppm" "$ttmp.t.ppm"
composite -verbose -compose multiply "$ttmp.p.ppm" "$ttmp.t.ppm" "$ttmp.u.ppm"
convert -verbose "$ttmp.u.ppm" -filter Gaussian -resize 50% "$ttmp.v.ppm"
rm -f "$ttmp.c.ppm"
rm -f "$ttmp.p.ppm"
rm -f "$ttmp.t.ppm"
rm -f "$ttmp.u.ppm"
cjb2 -clean -lossy -dpi "$tdpi" "$ttmp.m.pbm" "$ttmp.m.pbm.djvu"
c44 -dpi "$tdpi" -bpp 0.50 "$ttmp.s.ppm" "$ttmp.q.ppm.djvu"
c44 -dpi "$tdpi" -bpp 0.02,0.04,0.08 "$ttmp.v.ppm" "$ttmp.r.ppm.djvu"
rm -f "$ttmp.m.pbm"
rm -f "$ttmp.s.ppm"
rm -f "$ttmp.v.ppm"
djvuextract "$ttmp.m.pbm.djvu" Sjbz="$ttmp.Sjbz.cnk"
djvuextract "$ttmp.q.ppm.djvu" BG44="$ttmp.FG44.cnk"
djvuextract "$ttmp.r.ppm.djvu" BG44="$ttmp.BG44.cnk"
rm -f "$ttmp.m.pbm.djvu"
rm -f "$ttmp.q.ppm.djvu"
rm -f "$ttmp.r.ppm.djvu"
djvumake "$src.djvu" INFO=,,"$tdpi" Sjbz="$ttmp.Sjbz.cnk" FG44="$ttmp.FG44.cnk" BG44="$ttmp.BG44.cnk"
rm -f "$ttmp.Sjbz.cnk"
rm -f "$ttmp.FG44.cnk"
rm -f "$ttmp.BG44.cnk"
Скрипт по умолчанию работает с разрешением 300dpi (первый необязательный параметр) и с 50% потолком выделения контура (второй необязательный параметр). Примеры:
$ bash djvu-colors-v4.sh scan0001.png
$ bash djvu-colors-v4.sh scan0002.jpg 600 75