Брошюруем djvu – как сделать djvu книгу

Есть места (например, трамвай), где очень кстати бывает почитать книжку, но читать с экрана в таких местах так же невозможно, как и с листов А4. В конце концов, я решил преобразовать djvu в удобную брошюру. Процесс это достаточно творческий, зависит от качества книги, от её объёма и размера листов… поэтому универсального инструмента я так пока и не нашёл (не сделал). Здесь я описываю набор приёмов, комбинируя которые можно быстро добиться желаемого результата.
djvu книга

Задачи: надо распечатать в виде брошюрки книгу:
• формат: djvu
• качество сканирования: отвратительное, бумага серая, буквы потёртые
• объём: страниц больше сотни и в одну брошюрку никак не поместится
• размер станиц: в районе 1392×2361 (в пикселях), но все страницы немного разные.

Это достаточно стандартная ситуация и общепринятые цифры и параметры.

Приступим. Нам надо сделать несколько брошюрок. Для примера, будем брошюровать страницы с 74 по 121. Обратите внимание, количество страниц кратно четырём.

Для работы с изображениями нам понадобится пакет djvulibre и набор инструментов ImageMagick. Оба средства распространяются свободно.
Разбираем djvu-файл на страницы

Предлагаю вот такую разбиралку:

#!/bin/sh

first_page=74
last_page=121

i=$first_page
while test $i -le $last_page
do
echo "ddjvu: $i"
ddjvu -format=ppm -page=$i file.djvu temp.ppm
echo "convert: $i"
convert temp.ppm -normalize -modulate 150,300 -monochrome gif:page-$i.gif
rm temp.ppm
i=$(($i+1))
done

Этот скрипт пробегает в цикле по указанному интервалу страниц. Сперва вытаскивает страницу утилитой ddjvu в отдельный файл temp.ppm. Затем преобразует этот файл в page-[номер].gif. Попутно производятся магические действия: нормализация цветов, повышение яркости и контрастности и преобразование к монохромному виду. Первое рекомендую делать всегда — хуже не будет. Второе позволяет нивелировать низкое качество сканирования. Рекомендую поиграть параметрами 150 и 300 для получения наилучшего результата. Очень советую преобразовать к чёрно-белому формату именно на этом этапе. Это не только сэкономит дисковое пространство и процессорное время, но главное — не монохромные изображения не всегда хорошо печатаются.

Определяем размеры страниц
Часто встречаются djvu-файлы, с разными страницами. То есть размеры чуть-чуть подгуливают пикселей на 10-20. Вот perl-скрипт, определяющий максимальный размер:

#!/usr/bin/perl -w
sub max {return $_[0]>$_[1]?$_[0]:$_[1]}
my ($w, $h)=(0, 0);
foreach () {
my $s=qx{identify $_};
die unless ($s=~m/(\d+)x(\d+)/);
$w=max($w, $1);
$h=max($h, $2);
print "$1\t$2\n";
}
print "w=$w h=$h\n";

Он анализирует все файлы с именами page-*.gif в текущей директории.
Сборка листов

Из наших 48 страниц нам надо собрать 24 листа.

Во-первых, определимся с разрешением. Размер листа А4 при разрешении 300 dpi — 3508×2479 пикселя. То есть наши странички как раз при таком разрешении хорошо вписываются по две на лист. Если разрешение окажется нестандартным, то всё надо будет отмасштабировать. С этим справится и convert и ddjvu.

Мой опыт печати на разных принтерах убедил меня, что в вопросах, касающихся области печати принтера нельзя верить не только стандартам, но и документации на принтер. Максимальным «безопасным» размером страницы мне представляется 3350×2300 (при 300 dpi). Но даже на этот размер некоторые принтеры могут реагировать неадекватно; например, самопроизвольно уменьшать dpi (изображение при этом увеличивается).

Теперь собираем странички. Следующий скрипт выдаёт последовательность вызовов convert для сборки страниц:

#!/usr/bin/perl -w

my $pp=24; # кол-во листов (на листе 2 стр)
my $pi=74; # номер первой страницы

sub p {
print "convert blank.png page-$_[0].gif -geometry +0+0".
" -composite page-$_[1].gif -geometry +1392+0".
" -composite -rotate $_[3] -monochrome sh-$_[2].gif\n";
}

for (my $p=0; $p<$pp; $p++) { my ($a, $b)=map {$_+$pi} ($p, $pp*2-$p-1); if ($p%2) { # 1 3 5.. p $a, $b, $p, 90; } else { # 0 2 4.. p $b, $a, $p, -90; } }

Как видите, ему надо задать только количество листов и номер первой страницы. То, что выдаст этот скрипт можно почитать, а можно передать sh, не читая.

В результате файлы page-[номер].gif будут пережёваны и появятся файлы sh-[номер].gif. Это и есть страницы.

Печать
Напечатать полученные картинки можно как угодно и на чём угодно. Я предпочитаю командную строку и лазерный принтер.

Поэтому сперва я конвертирую gif в pcl (поток команд принтера):

#!/bin/sh
for i in sh-*.gif
do
echo $i
convert -density 300 $i pcl:chap3/${i%gif}pcl
done

Pcl-файлы складываются в директорию chap3.

А потом, я просто отправляю эти файлы на принтер без какой-либо дальнейшей обработки.

Сперва надо отправить все чётные листы: 0, 2, 4, 6… в нашем случае, последним будет файл ch-22.pcl. Потом положите отпечатанную с одной стороны бумагу так, чтобы верх листа (листа, а не страницы) остался там же, а печать происходила на другой стороне. Положили? Последнее усилие — разберитесь, как вам печатать нечётные страницы: от 1 до 23 или наоборот. Это зависит от того, как устроена подача бумаги у вашего принтера. Мне кажется, что на большинстве принтеров печатать следует по убыванию.

Вот и всё.

Замечание про lpd
Если вы печатаете через lpd, то создайте принтер, который не фильтрует данные и пользуйтесь им.

Фильтр:

/bin/cat && exit 0
exit 2

В /etc/printcap пропишите новый принтер с этим фильтром (параметр записи if).

Теперь можно печатать без фильтрации:

lpr -Pимя_принтера имя_файла

Приятного чтения брошюр.


Оставить комментарий





Статистика

Рейтинг@Mail.ru