Программирование
On-line приложения
Почитать
Web-сервер Apache
Печать и форматирование
MySQL
Разные рецепты
Сборка/установка
Справки
Философия
Мой опыт
Скачать
Программы на Tcl/Tk (GUI)
Программы на Python/Tk (GUI)
Программы (CLI)
Help
Хобби
Фракталы
on-line
Язык для рисования фракталов
Гиперкуб
Теория относительности
Ампуллярии
Преподавание
Студенту/абитуриенту
Мой опыт
Автора!

Брошюруем djvu

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

djvu книга

Задачи: надо распечатать в виде брошюрки книгу:

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

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

Приступим. Нам надо сделать несколько брошюрок. Для примера, будем брошюровать страницы с 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 (<page-*.gif>) {
  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 — 3508x2479 пикселя. То есть наши странички как раз при таком разрешении хорошо вписываются по две на лист. Если разрешение окажется нестандартным, то всё надо будет отмасштабировать. С этим справится и convert и ddjvu.

Мой опыт печати на разных принтерах убедил меня, что в вопросах, касающихся области печати принтера нельзя верить не только стандартам, но и документации на принтер. Максимальным «безопасным» размером страницы мне представляется 3350x2300 (при 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имя_принтера имя_файла

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

Эта страница набрала не малую популярность, её посещает множество людей, поэтому я решил провести небольшое исследование. Если у вас есть комментарий, если вы сочли полученную информацию полезной, не полной, или вообще бесполезной, вы можете высказать своё мнение, пожелания, дополнения.

Если вы ожидаете получить от меня ответ или разъяснение, пожалуйста укажите e-mail, ICQ или другую контактную информацию.
Ваше сообщение не появится на странице, а просто отправится мне.

© 1999 − 2008 Мичурин Алексей — http://www.michurin.com.ru/