PDF имеет дополнительный пробел во всех словах после запуска через Ghostscript

10

Этот PDF был создан Abbyy Finereader 10:

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

Вы можете скопировать и вставить первое предложение и получить этот (очень хороший) текстовый результат:

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

После некоторой обработки с Ghostscript 9.02 (64-битная Windows) я получаю этот файл:

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

Теперь первое предложение выглядит странно - перед последним символом каждого слова есть дополнительный пробел.

Der »Bun d Deutsche r GymnastikSchulleiter« wurd eam 20. Ноябрь 195 г. 5 лет назад Зусамменкунт в Лейтенерине и Лейте в частном и немецком ГимнастикаАвсбилдунгсштетт и гегрюндет.

Это имеет основной негативный эффект: вы не можете искать целые слова в Acrobat Reader. Я могу воспроизвести эффект с помощью следующего минимального набора параметров для Ghostscript:

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

Любые идеи?

Курт Пфайфл
источник
@Erwin Jurschitza: не могли бы вы сохранить ссылку на ваш файл from_abbyy.pdf на некоторое время, чтобы его можно было найти даже через несколько месяцев?
Курт Пфайфл
@pipitas: Нет проблем, это на Amazon S3.

Ответы:

8

Я нашел это интересной проблемой и присмотрелся ...

Во-первых, я использовал qpdfинструмент командной строки для распаковки потоков данных PDF, чтобы лучше видеть исходные коды обоих файлов:

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

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

Глядя на одно из первых случаев, когда вставляется лишний пробел (это оригинальная строка «Bund Deutscher Gymnastik-Schulleiter», превращающаяся в «Bun d Deutsche r GymnastikSchulleiter» ), я нахожу следующие фрагменты PDF:

В 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

В 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

Чтобы дать вам небольшое представление о том, что означают используемые здесь графические операторы PDF, вот краткий список:

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

Как вы можете видеть, Ghostscript заменил оригинальный Tm( текстовая матрица ) оператор на Td( перемещать текущую точку текста ), а также добавил дополнительный 2.16501 0 Td... Я не знаю, почему это так. Я отправлю сообщение об ошибке в bugzilla Ghostscript [*] и посмотрю, заинтересованы ли они в его решении.

Обратите внимание, что эта проблема не возникает, если я использую Linux Acrobat Reader 9.4.2 и использую действие меню «Файл -> Сохранить как текст ...» . В этом случае нет дополнительных пробелов (но есть несколько дополнительных разрывов строк). В Linux также текст не доступен для правильного поиска, а также показывает дополнительные пробелы при копировании и вставке ....


[*] Я обновлю здесь номер ошибки, когда я это сделаю.


Обновить:

Поразмыслив немного о замененном Tmоператоре, теперь я думаю, что это не должно быть корнем проблемы.

Понимая это, я попытался выполнить преобразование с помощью Ghostscript v8.71 вместо v9.02. И что мне сказать? Проблема с копированием и вставкой не возникает при выводе v8.71!

Это значит: в Ghostscript 9.02 есть проблема, которой не было в 8.71. Скорее всего, это связано с метриками шрифта, встроенными в выходной PDF. Поскольку приведенные выше фрагменты PDF-файла совпадают в выходной версии v8.71 и в выходной версии v9.02 ....

Обновление 2:

URL записи об ошибке в bugzilla Ghostscript:

Обновление 3:

Эта ошибка, кажется, тем временем исправлена. Я не вижу, чтобы это случилось с версиями Ghostscript, с которыми я снова тестировал: текущую версию Git (v9.10GIT) и Ghostscript v9.06.

Курт Пфайфл
источник
@pipitas: Большое спасибо за анализ этого!
5

Если вы отсканируете страницу с текстом в PDF и запустите на ней приложение OCR, текст будет добавлен на страницу, но «режим визуализации текста» будет установлен как невидимый. Он есть, но не отображается на экране (или на бумаге, если напечатан). То, что вы видите или печатаете, является исходным отсканированным изображением.

Как мы можем сделать невидимый текст видимым?

Ну, мы можем отредактировать PDF ... Код PDF, чтобы сделать текстовый рендеринг невидимым, таков:

3 Tr

Вы не можете найти эту строку (пока) ни в оригинальном файле from_abbyy.pdf, ни в файле from_ghostscript.pdf, поскольку части PDF-файлов сжаты. Поэтому мы распаковываем их насколько это возможно с помощью qpdf:

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

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

Теперь мы можем легко найти вышеуказанную строку (и в каждом файле есть только одно вхождение).

Давайте переключим это на один из видимых режимов рендеринга текста. В целом, мы можем выбрать один из 8 режимов рендеринга текста:

 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

Если я использую режим «заливки», текст с OCR, вероятно, будет выглядеть не очень хорошо поверх основного сканированного изображения. Поэтому я предпочитаю вариант «инсульт». Поэтому я просто изменяю над строкой, чтобы читать

 1 Tr

Глядя на этот измененный PDF, мне не нравится, потому что ширина линии по умолчанию слишком толстая, на мой вкус. Кроме того, цвет контура обводки черный (по умолчанию); Я бы предпочел красный, чтобы иметь контраст с первоначально отсканированными формами. Поэтому я добавляю код в начало этой строки, который устанавливает ширину линии равной четверти точки:

 .25 w

и некоторые другие, чтобы установить цвет обводки на красный:

 1 0 0 RG

Полная строка теперь выглядит так:

 .25 w 1 0 0 RG 1 Tr

Это все.

Обратите внимание, что наши небольшие манипуляции повредили файл, потому что его "TOC" (в техническом плане: его xrefтаблица) теперь больше не будет действительным. Тем не менее, Acrobat Reader или Acrobat Professional по-прежнему открывают его (даже не жалуясь) и молча «восстанавливают» раздел xref файла. Другие программы просмотра PDF могут отклонить файл, но сейчас нам все равно ...

Вот скриншоты результата: увеличено до ширины окна (Первый скриншот увеличен до ширины окна.) увеличено до 800% (Второй скриншот увеличен до 800%.)

Красные контуры - это отсканированный текст, видимый сейчас, как мы и хотели.

Я выполнил ту же процедуру, что и описанную выше для обоих файлов from_abbyy.pdf и after_ghostscript.pdf . Я открыл оба результата в 2 разных экземплярах Acrobat Reader. Если мы сделаем так, чтобы они оба увеличивали до одинакового значения и максимизировали оба окна, тогда будет легко переключаться между двумя файлами [alt]+[tab]. Это хороший способ выявить даже самые тонкие различия в рендеринге между двумя PDF-файлами.

Мой результат: нет даже одного пикселя, различного между входом Ghostscript (v9.02) и его выводом для этого файла. Но есть большая разница, если вы хотите скопировать и вставить текст ...

Курт Пфайфл
источник
1

Я не вижу описанную проблему. Я открыл PDF-файл «после» в Acrobat Professional 9.0, и текст скопирован и вставлен правильно.

Ghostscript полностью интерпретирует файл PDF и создает новый файл PDF на основе того, что он интерпретировал, он не имеет никакого отношения к исходному файлу, кроме того, что записывает положение текста.

Благодаря богатому набору возможностей PDF можно размещать символы в одном и том же месте, используя несколько различных методов. Так что нет ничего плохого или неожиданного в том, как GS создает PDF-файл.

Учитывая, что текст может быть сохранен корректно, это зависит от эвристики Acrobat, решающей, являются ли два «соседних» символа соседними или имеют пробел между ними, когда обрабатываются как последовательный ASCII.

Я не верю, что проблема может заключаться в метриках встроенного шрифта по той простой причине, что шрифт не внедрен :-) Используемый шрифт - Helvetica, который не встроен в документ, и поэтому Acrobat (по крайней мере, для меня) использует ArialMT. Обратите внимание, что «оригинальный» PDF-файл также не содержит шрифтов.

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

KENS
источник
@ user701996: Интересно - нет проблем с Acrobat Pro 9.0? Моя Acrobat Reader X (10.0.1, Windows) имеет проблему.
@ user701996: я открыл файл в Acrobat Professional 9.4.4. Copy'n'paste из после -file не работает. Сохранить как текст ... однако работает ...
Курт Пфайфл
@ user701996: Даже если шрифт не внедрен, метрики шрифта есть . Хм, если только шрифт не является одним из «Base 14» .... Так что вы можете быть правы в этом случае. Я посмотрю поближе.
Курт Пфайфл
@ user701996: Похоже, вы один из людей Ghostscript. Ты?
Курт Пфайфл
1

Из отчета об ошибке Ghostscript по адресу:

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


Теперь я смог воспроизвести проблему, и это не регрессия из 8.71, это прогресс (и изменение Adobe).

8.71 поставляется с ошибкой, из-за которой он пишет недопустимые ToUnicode CMaps. Вводящая в заблуждение и противоречивая документация Adobe привела к тому, что CMap был написан как CMap, тогда как на самом деле CMap ToUnicode имеют свои собственные несовместимые правила.

ToUnicode CMaps обычно используются только для поиска и копирования / вставки. Как следует из названия, они используются для сопоставления кодов символов с кодовыми точками Unicode. ToUnicode CMap в файле PDF 8.71 не используется, поскольку он недопустим, тот, что в более поздних версиях, является действительным, и Acrobat, как известно, использует его.

Похоже, что в Acrobat Reader вплоть до 9.2 включительно существование данных ToUnicode не имеет значения. В какой-то момент после 9.2 механизм поиска изменился, и Acrobat, похоже, использует два разных механизма в зависимости от того, присутствует ли ToUnicode CMap. У меня нет доступа к Acrobat Pro после 9.2 и только недавно установленного Reader X, у меня нет ничего между.

Метод «без Юникода» работает во всех версиях Acrobat, метод «Юникод» не работает в более новых версиях.

Я показал это с помощью интервала между ссылками на CMap ToUnicode из FontDescriptor. При необходимости я могу сделать доступными различные файлы, но они большие, поскольку они распакованы.

Так как поиск в PDF - это эвристическое усилие, невозможно гарантировать результат. Изменения в поведении произошли из-за Acrobat, а не Ghostscript, и изменение в Ghostscript должно было исправить реальную ошибку, так что прогресс, а не регрессия.

KENS
источник
0

Чтобы проверить, связана ли эта проблема со «внедренностью» шрифта или нет, я сделал другое преобразование в Linux. Я использовал эту командную строку, чтобы Ghostscript встраивал используемые шрифты:

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

Ghostscript покажет этот вывод:

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 имеет встроенные шрифты из семейства шрифтов с именем NimbusSanL . Так что больше нет ArialMT , так как он использовался для рендеринга на экране Acrobat Reader в качестве замены отсутствующего Helvetica (см. Также комментарии user701996 выше). Обратите внимание, что Ghostscript переименует этот шрифт в Helvetica, как только он будет встроен. Но это не проблема, потому что NimbusSanL был создан как клон Helvetica ...

Однако даже для этого выходного файла PDF копирование и вставка из Acrobat Reader не будут работать хорошо. Несмотря на то, что Reader больше не нужно использовать ArialMT для замены Helvetica. Reader теперь использует встроенный клон NimbusSanL / Helvetica.

На данный момент мы установили эти факты о копировании и вставке текста из Acrobat Reader или Acrobat Professional:

  • Вывод Ghostscript v9.02 не работает достаточно хорошо для этого файла.
  • Это тот случай, если шрифт внедрен GS или нет.
  • Это касается GS в Windows XP, а также GS в Linux.

  • Вывод Ghostscript v8.71 работает достаточно хорошо для этого файла.

  • Это тот случай, если шрифт внедрен GS или нет.
  • Это касается GS в Windows XP, а также GS в Linux.

  • Даже для вывода, где copy'n'paste не работает, Save as Text ... делает.

Я до сих пор не понимаю, почему это должно быть так. Но это явно выглядит как своего рода (возможно, незначительный) регресс Ghostscript на пути с v8.71 по 9.02.

Теперь давайте попробуем другое программное обеспечение для просмотра PDF с «критическими» PDF-файлами:

  • Adobe Reader X внутри Wine в Linux: copy'n'paste создается так же, как и в v9.4.4.
  • Evince v2.32.2 для Linux: copy'n'paste работает.
  • PDFXChange Viewer 2.5 (сборка 191) в Windows XP Prof: копирование и вставка работает.
  • MuPDF reader 0.8 в Linux: не знаю, как скопировать и вставить, но «поиск» работает безупречно.
  • Найдено с.т. называется «PDF Viewer 0.1.7» в Linux: копирование и вставка работает.
  • SumatraPDF v1.5 внутри Wine в Linux: copy'n'paste работает.
  • SumatraPDF v1.5.1 в Windows XP: копирование и вставка работает.
  • FoxitReader 4.3.1.0113 в Windows XP: копирование и вставка работает.
  • Nitro PDF Reader внутри Wine на Linux: копирование и вставка работает.

Обратите внимание, что между всеми «рабочими» программами для чтения PDF, где мой вердикт был произведением copy'n'paste , есть и другие, но очень незначительные различия . Например, пропущенная черточка здесь, или двойные пробелы между словами там, и другие подобные вещи ... У меня нет никакого объяснения в настоящее время, почему это может быть, но, вероятно, это та же самая основная причина, почему существует большой разрыв между продуктами Adobe (у которого нет рабочей copy'n'paste для этого файла) один, который был один, и "остальной мир" - с другой.

Курт Пфайфл
источник