Bywa że klient przysyła Ci treści do umieszczenia na stronie z krótkim komentarzem – „Tak to sobie wyobrażam”. Otwierasz maila i widzisz plik PDF. Są tam pięknie ułożone teksty okraszone kolorowymi fotografiami, wszystko elegancko poukładane i skomponowane, a Ty drapiesz się w głowę i nic nie mówisz bo szkoda słów. Jeśli jesteś webdeveloperem, specjalistą od cięcia i stylowania to szczerze Ci współczuję. Jeśli jednak Twoim jedynym zadaniem jest wydobycie z tego PDF-a wszystkich tekstów oraz grafik to jest nadzieja.
Klikacze lub marzyciele często patrzący w „okna” mogą skorzystać z jednej z rad proponowanych w artykule How to Extract Text from a PDF document lub How Can I Get Text or Images Out of a PDF File?. Alternatywą jest użycie konsoli i wierzcie mi w tym przypadku jest to o wiele wygodniejsze i szybsze rozwiązanie.
Do wyłuskania tekstów używamy programu „pdftotext” będącego częścią programu „xpdf”
pdftotext ./dokument.pdf |
Gdyby były problemy z polskimi literami warto zapoznać się z opcją „enc”:
pdftotext -enc Latin2 dokument.pdf |
albo
pdftotext -enc UTF-8 dokument.pdf |
Z obrazkami robimy identycznie tylko, że używając programu „pdfimages” także będącego konsolowym narzędziem „xpdf-a”
pdfimages ./dokument.pdf przedrostek_obrazka |
Program „pdfimages” zapisuje obrazki w formacie plików „ppm” więc trzeba je jeszcze przekonwertować do jpg-ów np. przy pomocy programu „pnmtojpeg” będącego częścią większego pakietu programów graficznych „Netpbm„.
for pic in *.ppm do pnmtojpeg "${pic}" > "${pic/%ppm/jpg}" done |
O ile programy „pdftotext” jak i „pdfimages” miałem już w systemie to „pnmtojpeg” trzeba było doinstalować i kiedy już to zrobiłem i przetestowałem przypomniałem sobie, że mam przecież zainstalowanego „ImageMagick-a„, którego użycie okazało się jeszcze prostsze.
mogrify -format jpg *.ppm |
Pliki wynikowe uzyskane po zastosowaniu „mogrify” są większe co sugeruje mniejszą stratę na jakości, poza tym jak się ma „ImageMagick-a” to można z tymi plikami zrobić przy okazji dużo więcej np. automatycznie przeskalować, utworzyć miniatury, dodać ramki czy co nam tam jeszcze przyjdzie do głowy. Tworząc skrypt, który wszystkie wyżej przytoczone komendy zbiera w jedną zdecydowałem się właśnie na „mogrify”.
Plik extractpdf.sh
#!/bin/sh if [ $# -lt 1 ]; then echo "Usage: `basename $0` file.pdf" exit 1; fi PDF=$1 FILE_NAME=`basename ${PDF%.*}` TEMP_DIR="`dirname $PDF`/${FILE_NAME}" if [ ! -e $TEMP_DIR ]; then mkdir -p $TEMP_DIR; fi pdftotext $PDF "${TEMP_DIR}/${FILE_NAME}.txt" pdfimages $PDF "${TEMP_DIR}/${FILE_NAME}" mogrify -format jpg ${TEMP_DIR}/*.ppm find ${TEMP_DIR}/ -name "*.ppm" -exec rm {} \; |
Skrypt oszczędza masę pisania poza tym jest uniwersalny więc nadaje się do wielokrotnego użytku. Teraz wystarczy nadać mu prawa do wykonywania
chmod +x ./extractpdf.sh |
i cała praca to wywołanie skryptu z podaniem ścieżki do pliku pdf w parametrze
./extractpdf.sh ./dokument.pdf |
Można pokusić się o rozbudowę tego skryptu o sprawdzanie czy wymagane programy są zainstalowane oraz zwiększyć funkcjonalność poprzez próbę użycia „pnmtojpeg” w przypadku jeśli „ImageMagick” nie jest zainstalowany.
Plik extractpdf2.sh
#!/bin/bash if [ $# -lt 1 ]; then echo "Usage: `basename $0` file.pdf" exit 1; fi type -P pdftotext &>/dev/null || { echo "I require pdftotext but it's not installed. Aborting." >&2; exit 1; } type -P pdfimages &>/dev/null || { echo "I require pdfimages but it's not installed. Aborting." >&2; exit 1; } if type -P mogrify >/dev/null; then CONVERTER="mogrify" else type -P pnmtojpeg &>/dev/null || { echo "I require the mogrify or pnmtojpeg but none of them is not installed. Aborting." >&2; exit 1; } CONVERTER="pnmtojpeg" fi PDF=$1 FILE_NAME=`basename ${PDF%.*}` TEMP_DIR="`dirname $PDF`/${FILE_NAME}" if [ ! -e $TEMP_DIR ]; then mkdir -p $TEMP_DIR; fi pdftotext $PDF "${TEMP_DIR}/${FILE_NAME}.txt" pdfimages $PDF "${TEMP_DIR}/${FILE_NAME}" if [ $CONVERTER = 'mogrify' ]; then mogrify -format jpg ${TEMP_DIR}/*.ppm find ${TEMP_DIR}/ -name "*.ppm" -exec rm {} \; else for PIC in ${TEMP_DIR}/*.ppm do pnmtojpeg "${PIC}" > "${PIC/%ppm/jpg}" rm $PIC done fi |
UWAGA!!! Użycie „type -P” wymaga skorzystania konkretnie z powłoki „bash” gdyż w „sh” program „type” nie ma opcji „-P” i traktuje ją jak ścieżkę do pliku co kończy się komunikatem błędu (-P: not found). Dlatego pomimo, że plik dalej nazywa się extractpdf.sh to zamiast „#!/bin/sh” należy wpisać „#!/bin/bash”.
To oczywiście nie wyczerpuje naszych możliwości. Zaproponowane przeze mnie narzędzie to niezbędne minimum. Stworzenie tego skryptu kosztowało mnie trochę czasu ale jest to praca jednorazowa. Podobnie miałem ze skryptem do generowania miniatur za to obecnie stale mam go w swoim arsenale i wierzcie mi, że suma sumarum zaoszczędził mi już naprawdę wiele czasu.