PDF ma dodatkowe puste miejsce we wszystkich słowach po przejściu przez Ghostscript

10

Ten plik PDF został stworzony przez Abbyy Finereader 10:

http://ebooks.zeitr.org/from_abbyy.pdf

Możesz skopiować i wkleić pierwsze zdanie i uzyskać ten (bardzo dobry) wynik tekstowy:

Der »Bund Deutscher Gymnastik-Schulleiter« wurde am 20 listopada 1955 anläßlich einer Zusammenkunft der Leiterinnen und Leiter der privaten deutschen Gymnastik-Ausbildungsstätten gegründet.

Po przetworzeniu za pomocą Ghostscript 9.02 (64-bitowy system Windows) otrzymuję ten plik:

http://ebooks.zeitr.org/after_ghostscript.pdf

Teraz pierwsze zdanie wygląda dziwnie - przed ostatnim znakiem każdego słowa jest spacja.

Der »Bun d Deutsche r GymnastikSchulleiter« wurd eam 20. Novembe r 195 5 anläßlic h eine r Zusammenkunf t der Leiterinne n un d Leite r de r private n deutsche n GymnastikAusbildungsstätte n gegründet.

Ma to główny negatywny skutek, że nie można wyszukiwać całych słów w programie Acrobat Reader. Mogę odtworzyć efekt przy użyciu następującego minimalnego zestawu parametrów Ghostscript:

-sDEVICE=pdfwrite ^
-dBATCH ^
-dNOPAUSE ^
-sstdout="myStdOut" ^
-sOutputFile="myDestFile.pdf" ^
 mySourceFile.pdf

Jakieś pomysły?

Kurt Pfeifle
źródło
@Erwin Jurschitza: czy mógłbyś zachować link do pliku from_abbyy.pdf przez jakiś czas, aby można go było odzyskać nawet po kilku miesiącach?
Kurt Pfeifle
@pipitas: Nie ma problemu, jest na Amazon S3.

Odpowiedzi:

8

Uważam to za interesujący problem i przyjrzałem się bliżej ...

Po pierwsze, użyłem qpdfnarzędzia wiersza polecenia do rozpakowania strumieni danych PDF, aby lepiej widzieć kody źródłowe obu plików:

qpdf.exe ^
   --qdf ^
     from_abbyy.pdf ^
     qdf--from_abbyy.pdf

qpdf.exe ^
   --qdf ^
     after_ghostscript.pdf ^
     qdf--after_ghostscript.pdf

Patrząc na jedno z pierwszych przypadków, w których wstawiana jest dodatkowa przestrzeń (jest to oryginalny ciąg „Bund Deutscher Gymnastik-Schulleiter” zamieniający się w „Bun d Deutsche r GymnastikSchulleiter” ), znajduję następujące fragmenty PDF:

W qdf - from_abbyy.pdf:

( Deutsche) Tj
0 Tc
(r) Tj
1 0 0 1 143.236 265.140 Tm     %% Tm = 'text matrix' operator
3.569 Tw
0.706 Tc
( Gymnastik-Schulleite) Tj

W qdf - after_ghostscript.pdf:

( Deutsche)Tj
0 Tc
36.235 0 Td                    %% extra Td = 'move text current point' operator
(r)Tj
2.16501 0 Td                   %% Td = 'move text current point' instead of Tm
3.569 Tw
0.706 Tc
( Gymnastik-Schulleite)Tj

Oto krótka lista, aby dać ci pojęcie, co oznaczają operatorzy grafiki PDF.

Tj - show text
Tc - set character spacing
Tm - set text matrix
Tw - set word spacing
Td - move text current point

Jak widać, Ghostscript zastąpił pierwotny operator Tm( matryca tekstowa ) operatorem Td( przenieś bieżący punkt tekstu ), a także dodał dodatkowy 2.16501 0 Td... Nie wiem, dlaczego tak jest. Prześlę raport o błędzie do bugzilli Ghostscript [*] i zobaczę, czy są zainteresowani jego rozwiązaniem.

Zauważ jednak, że ten problem nie występuje, jeśli korzystam z programu Linux Acrobat Reader 9.4.2 i używam akcji menu „Plik -> Zapisz jako tekst ...” . W takim przypadku nie ma dodatkowych spacji (ale kilka dodatkowych podziałów wiersza). Również w systemie Linux tekst nie jest poprawnie przeszukiwalny, a także pokazuje dodatkowe spacje podczas kopiowania i wklejania ....


[*] Zaktualizuję tutaj numer błędu, kiedy to zrobię.


Aktualizacja:

Po Tmzastanowieniu się trochę nad zastąpionym operatorem, teraz myślę, że nie powinno to być przyczyną problemu.

Uświadamiając sobie to, próbowałem dokonać konwersji za pomocą Ghostscript v8.71 zamiast v9.02. A co mam powiedzieć? Problem kopiowania i wklejania nie występuje w przypadku wyjścia w wersji 8.71!

To znaczy: w Ghostscript 9.02 występuje problem, którego nie było w 8.71. Najprawdopodobniej ma to związek z metrykami czcionek osadzonymi w wyjściowym pliku PDF. Ponieważ cytowane powyżej fragmenty PDF są takie same w danych wyjściowych w wersji 8.71 jak w danych wyjściowych w wersji 9.02 ...

Aktualizacja 2:

URL wpisu błędu w bugzilli Ghostscript:

Aktualizacja 3:

Tymczasem ten błąd został naprawiony. Nie widzę, aby stało się to z wersjami Ghostscript, które ponownie przetestowałem na: bieżącym Git (v9.10GIT) ani z Ghostscript v9.06.

Kurt Pfeifle
źródło
@pipitas: Dziękuję bardzo za przeanalizowanie tego!
5

Jeśli zeskanujesz stronę z tekstem do pliku PDF i uruchomisz na niej aplikację OCR, tekst zostanie dodany do strony, ale „tryb renderowania tekstu” jest ustawiony na niewidoczny. Jest tam, ale nie jest renderowany na ekranie (lub na papierze, jeśli jest drukowany). To, co widzisz lub drukujesz, to oryginalny zeskanowany obraz.

Jak sprawić, by niewidoczny tekst był widoczny?

Możemy edytować plik PDF ... Kod PDF, aby ustawić renderowanie tekstu na niewidoczny, jest następujący:

3 Tr

Nie można znaleźć tego ciągu (jeszcze) w oryginale from_abbyy.pdf ani w from_ghostscript.pdf, ponieważ części plików PDF są skompresowane. Dlatego rozpakowujemy je w miarę możliwości za pomocą qpdf:

qpdf \
 --qdf \
   from_abbyy.pdf \
   qdf--from_abbyy.pdf

qpdf \
 --qdf \
   after_ghostscript.pdf \
   qdf--after_ghostscript.pdf

Teraz możemy łatwo znaleźć powyższy ciąg (w każdym pliku występuje tylko jedno wystąpienie).

Przełączmy to na jeden z widocznych trybów renderowania tekstu. Ogólnie rzecz biorąc, możemy wybrać jeden z 8 trybów renderowania tekstu:

 0 -  fill glyph shapes
 1 -  stroke glyph shapes
 2 -  fill, then stroke glyph shapes
 3 -  neither fill nor stroke glyph shapes (invisible)
 4 -  fill and add to path for clipping glyph shapes
 5 -  stroke glyph shapes and add to path for clipping
 6 -  fill, then stroke glyph shapes and add path for clipping
 7 -  add glyph shapes to path for clipping

Jeśli użyję trybu „wypełnienia”, tekst z OCR prawdopodobnie nie będzie wyglądał tak dobrze na górze skanowanego obrazu. Dlatego wolę wariant „obrysu”. Więc po prostu zmieniam powyżej linii, aby przeczytać

 1 Tr

Patrząc na ten zmodyfikowany plik PDF, nie podoba mi się to, ponieważ domyślna szerokość linii jest zbyt gruba jak na mój gust. Kolor obrysu konturu jest również czarny (domyślnie); Wolałbym czerwony, aby mieć kontrast z pierwotnie skanowanymi kształtami. Dlatego dodaję kod z przodu tej linii, który ustawia szerokość linii na ćwierć punktu:

 .25 w

i kilka innych, aby ustawić kolor obrysu na czerwony:

 1 0 0 RG

Cały wiersz brzmi teraz:

 .25 w 1 0 0 RG 1 Tr

To wszystko.

Pamiętaj, że nasza niewielka manipulacja spowodowała uszkodzenie pliku, ponieważ jego „ xrefspis treści” (pod względem technicznym: tabela) nie będzie już poprawny. Acrobat Reader lub Acrobat Professional mimo to nadal go otworzy (nawet bez narzekań) i cicho „naprawi” sekcję odnośnika w pliku. Inne przeglądarki plików PDF mogą odrzucić plik, ale na razie nas to nie obchodzi ...

Oto zrzuty ekranu wyniku: powiększony do szerokości okna (Pierwszy zrzut ekranu jest powiększony do szerokości okna.) powiększony do 800% (Drugi zrzut ekranu jest powiększony do 800%.)

Czerwone kontury to zeskanowany tekst, który jest teraz widoczny, dokładnie tak, jak tego chcieliśmy.

Przeprowadziłem tę samą procedurę jak opisano powyżej dla obu plików from_abbyy.pdf i after_ghostscript.pdf . Oba wyniki otworzyłem w 2 różnych instancjach Acrobat Reader. Jeśli sprawimy, że oba powiększą tę samą wartość i zmaksymalizują oba okna, łatwo będzie przełączać widok między dwoma plikami za pośrednictwem [alt]+[tab]. Jest to dobry sposób na ujawnienie nawet najlepszych różnic w renderowaniu między dwoma plikami PDF.

Mój wynik jest taki: nie ma nawet jednego piksela różnego między wejściem Ghostscript (v9.02) a wyjściem dla tego pliku. Ale jest duża różnica, jeśli chcesz skopiować i wkleić tekst ...

Kurt Pfeifle
źródło
1

Nie widzę opisanego problemu. Plik PDF „po” otworzyłem w programie Acrobat Professional 9.0, a tekst został poprawnie skopiowany i wklejony.

Ghostscript w pełni interpretuje plik PDF i tworzy nowy plik PDF na podstawie tego, co zinterpretował, nie ma żadnego związku z oryginalnym plikiem poza tym, że rejestruje pozycję tekstu.

Ze względu na bogaty zestaw funkcji PDF możliwe jest umieszczanie znaków w tym samym miejscu za pomocą wielu różnych metod. Nie ma więc nic złego ani nieoczekiwanego w sposobie, w jaki GS tworzy plik PDF.

Biorąc pod uwagę, że tekst można poprawnie zapisać, jest to kwestia heurystyki programu Acrobat, która decyduje, czy dwa „pobliskie” znaki sąsiadują ze sobą, czy też mają odstęp między nimi, gdy są traktowane jako kolejne ASCII.

Nie sądzę, że problemem mogą być metryki czcionek osadzonych z tego prostego powodu, że czcionka nie jest osadzona :-) Używana jest czcionka Helvetica, która nie jest osadzona w dokumencie, a więc Acrobat (przynajmniej dla mnie) używa ArialMT. Pamiętaj, że „oryginalny” plik PDF również nie zawiera czcionek.

W końcu przyjrzę się zgłoszonemu błędowi, ale niedługo to nastąpi i wątpię, aby można było (lub zrobić) coś z tym zrobić. Wydaje mi się, że jest to nieunikniona konsekwencja heurystyki. To może pomóc osadzić czcionki chociaż, tak że przynajmniej byłyby spójne.

KenS
źródło
@ user701996: Ciekawe - żadnych problemów z Acrobat Pro 9.0? Problem dotyczy mojego programu Acrobat Reader X (10.0.1, Windows).
@ user701996: Otworzyłem plik w programie Acrobat Professional 9.4.4. Kopiowanie i wklejanie pliku po nie działa. Zapisz jako tekst ... jednak działa ...
Kurt Pfeifle
@ user701996: Nawet jeśli czcionka nie jest osadzona, metryki czcionki . Hmmm, chyba że czcionka jest jedną z „Base 14”… Więc może masz rację w tym przypadku. Przyjrzę się bliżej.
Kurt Pfeifle
@ user701996: Brzmisz jakbyś był jednym z ludzi Ghostscript. Jesteś?
Kurt Pfeifle
1

Z raportu o błędach Ghostscript pod adresem:

http://bugs.ghostscript.com/show_bug.cgi?id=692206


Teraz byłem w stanie odtworzyć problem i nie jest to regresja z 8,71, to postęp (i zmiana Adobe).

8.71 dostarczony z błędem, który spowodował, że zapisał niepoprawne CMaps ToUnicode. Wprowadzająca w błąd i sprzeczna dokumentacja Adobe doprowadziła do tego, że CMap został napisany jako CMap, podczas gdy w rzeczywistości CMU ToUnicode mają swoje własne, niezgodne reguły.

ToUnicode CMaps są zwykle używane tylko do wyszukiwania i kopiowania / wklejania. Jak sama nazwa wskazuje, są one używane do mapowania kodów znaków na punkty kodowe Unicode. ToUnicode CMap w pliku PDF 8.71 nie jest używany, ponieważ jest niepoprawny, ten w późniejszych wersjach jest prawidłowy i Acrobat jest znany z jego używania.

Wygląda na to, że w programie Acrobat Reader do wersji 9.2 włącznie istnienie danych ToUnicode nie ma znaczenia. W pewnym momencie po 9.2 mechanizm wyszukiwania zmienił się i wydaje się, że Acrobat używa dwóch różnych mechanizmów, w zależności od obecności CMU ToUnicode. Nie mam dostępu do programu Acrobat Pro po wersji 9.2 i dopiero niedawno zainstalowałem Reader X, nie mam między nimi nic.

Metoda „bez Unicode” działa na wszystkich wersjach programu Acrobat, metoda „Unicode” nie działa na nowszych wersjach.

Pokazałem to przez białe odstępy odwołania do ToUnicode CMap z FontDescriptor. W razie potrzeby mogę udostępnić różne pliki, ale są one duże, ponieważ są dekompresowane.

Ponieważ wyszukiwanie jest heurystycznym wysiłkiem w PDF, nie będzie możliwe zagwarantowanie wyniku. Zmiana w zachowaniu wynika z Acrobata, a nie Ghostscript, a zmiana w Ghostscript polegała na naprawieniu prawdziwego błędu, a więc postępu, a nie regresji.

KenS
źródło
0

Aby sprawdzić, czy problem ten jest związany z „osadzeniem” czcionki, czy nie, dokonałem kolejnej konwersji w systemie Linux. Użyłem tego wiersza poleceń, aby Ghostscript osadził użyte czcionki:

gs \
 -o after_ghostscriptonlinux.pdf \
 -sDEVICE=pdfwrite \
 -dPDFSETTINGS=/prepress \
 -sEmbedAllFonts=true \
  from_abbyy.pdf

Ghostscript wyświetli następujące dane wyjściowe:

GPL Ghostscript SVN PRE-RELEASE 9.02 (2011-02-07)
Copyright (C) 2010 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
Loading NimbusSanL-Regu font from %rom%Resource/Font/NimbusSanL-Regu... 2776276 1420923 2081124 778943 3 done.
Loading NimbusSanL-ReguItal font from %rom%Resource/Font/NimbusSanL-ReguItal... 2853416 1529123 2137980 831640 3 done.
Loading NimbusSanL-Bold font from %rom%Resource/Font/NimbusSanL-Bold... 2970748 1643508 2194836 886454 3 done.

Ghostscript ma osadzone czcionki z rodziny czcionek o nazwie NimbusSanL . Więc nie ma już ArialMT , który był używany do renderowania na ekranie przez Acrobat Reader jako substytut brakującej Helveticy (patrz również komentarze użytkownika 701996 powyżej). Pamiętaj, że Ghostscript zmieni nazwę tej czcionki na Helvetica, gdy tylko zostanie osadzona. Ale to nie jest problem, ponieważ NimbusSanL został stworzony jako klon Helvetica ...

Jednak nawet w przypadku tego wyjściowego pliku PDF kopiowanie i wklejanie z programu Acrobat Reader nie będzie działać dobrze. Pomimo faktu, że Reader nie musi już używać ArialMT, aby zastąpić Helveticę. Czytnik wykorzystuje teraz wbudowany klon NimbusSanL / Helvetica.

Do tej pory ustaliliśmy następujące fakty dotyczące kopiowania i wklejania tekstu z Acrobat Reader lub Acrobat Professional:

  • Dane wyjściowe Ghostscript v9.02 nie działają wystarczająco dobrze dla tego pliku.
  • Dotyczy to tego, czy czcionka jest osadzona przez GS, czy też nie.
  • Tak jest w przypadku GS na Windows XP, a także GS na Linux.

  • Dane wyjściowe Ghostscript v8.71 CZY działa wystarczająco dobrze dla tego pliku.

  • Dotyczy to tego, czy czcionka jest osadzona przez GS, czy też nie.
  • Tak jest w przypadku GS na Windows XP, a także GS na Linux.

  • Nawet dla wyjścia gdzie copy'n'paste jest uszkodzony, Zapisz jako tekst ... robi.

Nadal nie rozumiem, dlaczego tak powinno być. Ale najwyraźniej wygląda to na jakąś (może niewielką) regresję Ghostscript na drodze od wersji 8.71 do wersji 9.02.

Teraz wypróbujmy inne oprogramowanie do przeglądania plików PDF z „krytycznymi” plikami PDF:

  • Adobe Reader X wewnątrz Wine w systemie Linux: kopiowanie i wklejanie jest tak samo jak w wersji 9.4.4.
  • Evince v2.32.2 w systemie Linux: działa kopiowanie i wklejanie.
  • PDFXChange Viewer 2.5 (build 191) w Windows XP Prof: kopiowanie i wklejanie działa.
  • Czytnik MuPDF 0.8 w systemie Linux: nie wiem, jak kopiować i wklejać - ale „wyszukiwanie” działa bezbłędnie.
  • Znaleziono s.th. o nazwie „PDF Viewer 0.1.7” w systemie Linux: kopiowanie i wklejanie działa.
  • SumatraPDF v1.5 wewnątrz Wine w systemie Linux: działa kopiowanie i wklejanie.
  • SumatraPDF v1.5.1 w systemie Windows XP: działa kopiowanie i wklejanie.
  • FoxitReader 4.3.1.0113 w systemie Windows XP: kopiowanie i wklejanie działa.
  • Nitro PDF Reader wewnątrz Wine na Linuksie: działa kopiowanie i wklejanie.

Zauważ, że istnieją jeszcze inne, ale bardzo niewielkie różnice między wszystkimi „działającymi” czytnikami PDF, w których moim zdaniem było kopiowanie i wklejanie . Na przykład brakująca kreska lub podwojone spacje między słowami i inne tego typu rzeczy ... Nie mam obecnie wyjaśnienia, dlaczego tak się dzieje, ale prawdopodobnie jest to ten sam główny powód, dla którego istnieje duża luka między produktami Adobe (które nie mają roboczego kopiowania i wklejania dla tego pliku) jeden z nich miał jeden, a „reszta świata” z drugiej.

Kurt Pfeifle
źródło