Удалить весь текст из файла PDF

#pdf-generation #ghostscript

#pdf-генерация #ghostscript

Вопрос:

Я использую Ghostscript для преобразования исходного файла PDF в массив изображений PNG. Прежде чем конвертировать страницу PDF в изображение PNG, мне нужно будет извлечь (удалить) весь текст из PDF, чтобы преобразованное изображение страницы содержало все остальные элементы, за исключением текста.

Могу ли я достичь этого с помощью Ghostscript или мне нужно будет изучить другие инструменты?

Меня также интересовал бы инструмент, который может читать-сохранить мой исходный PDF-файл, удалив весь текст.

Ответ №1:

Со времени моего предыдущего ответа разработка продолжалась, и теперь доступна новая опция, которая оправдывает новый ответ.

Самые последние версии Ghostscript поддерживают 3 новых параметра, которые позволяют удалить либо весь ТЕКСТ, либо все ИЗОБРАЖЕНИЯ, либо все ВЕКТОРНЫЕ элементы из PDF.

Чтобы удалить все ТЕКСТОВЫЕ элементы из входного PDF-файла, выполните

 gs -o no-more-texts.pdf -sDEVICE=pdfwrite -dFILTERTEXT   input.pdf
 

Чтобы удалить все элементы растрового ИЗОБРАЖЕНИЯ из входного PDF-файла, выполните

 gs -o no-more-texts.pdf -sDEVICE=pdfwrite -dFILTERIMAGE  input.pdf
 

Чтобы удалить все векторные элементы из входного PDF-файла, выполните

 gs -o no-more-texts.pdf -sDEVICE=pdfwrite -dFILTERVECTOR input.pdf
 

Конечно, вы также можете объединить любой из двух вышеуказанных параметров (объединение всех трех приведет к созданию пустых страниц.

Вот скриншоты страницы PDF, где оригинал содержал все три элемента, тогда как результирующие страницы выглядят по-другому.


Скриншот исходной страницы PDF, содержащей элементы «изображение», «вектор» и «текст».
Скриншот исходной страницы PDF, содержащей элементы quot;изображениеquot;, quot;векторquot; и quot;текстquot;.


Выполнение следующих 6 команд создаст все 6 возможных вариантов оставшегося содержимого:

 gs -o noIMG.pdf -sDEVICE=pdfwrite -dFILTERIMAGE ввод.pdf
gs -o noTXT.pdf -sDEVICE=pdfwrite -dFILTERTEXT ввод.pdf
gs -o noVCT.pdf -sDEVICE=pdfwrite -dFILTERVECTOR ввод.pdf

 gs -o onlyIMG.pdf -sDEVICE=pdfwrite -dFILTERVECTOR -dFILTERTEXT ввод.pdf
gs -o onlyTXT.pdf -sDEVICE=pdfwrite -dFILTERVECTOR -dFILTERIMAGE ввод.pdf
gs -o onlyVCT.pdf -sDEVICE=pdfwrite -dFILTERIMAGE -dFILTERTEXT ввод.pdf

На следующем рисунке показаны результаты:


Верхняя строка слева: весь «текст» удален; все «изображения» удалены; все «векторы» удалены. Нижняя строка слева: сохранен только «текст»; сохранены только «изображения»; сохранены только «векторы».
Верхний ряд слева: весь quot;текстquot; удален; все quot;изображенияquot; удалены; все quot;векторыquot; удалены. Нижняя строка слева: сохранен только quot;текстquot;; сохранены только quot;изображенияquot;; сохранены только quot;векторыquot;.


Ответ №2:

Вы можете добиться желаемого без Ghostscript, просто используя текстовый редактор.

  1. Преобразуйте сжатый PDF-файл в формат, содержащий (почти) все содержимое и потоки PDF-объектов, развернутые в удобочитаемую форму с помощью QPDF:
      qpdf --qdf --object-streams=disable input.pdf editable.pdf
     
  2. Откройте новый editable.pdf файл с помощью текстового редактора (который также изящно обрабатывает все оставшиеся двоичные двоичные объекты внутри PDF, такие как шрифт или ресурсы ICC).
  3. Найдите все вхождения TJ Tj строк и (операторы PDF, используемые для отображения текста) внутри потоков объектов PDF и замените их строками JT и jT соответственно (неопределенные, бессмысленные операторы PDF). Сохраните файл как edited.pdf .
  4. Теперь конвертируйте ваши edited.pdf изображения в PNG по мере необходимости.

Обратите внимание, что это все edited.pdf равно будет отображаться в большинстве программ просмотра PDF, но текст будет отсутствовать, как и предполагалось. Однако будет легко восстановить текст снова, восстановив исходные операторы TJ / Tj и, таким образом, отменяя любые ручные изменения.


В «нормализованной» форме, созданной qpdf приведенной выше командой, объекты с потоками обычно выглядят так (где NNN — целое число):

 NNN 0 obj
<<
   % Here are the key:value pairs of the object dictionary
   /Key1 somevalue1
   /Key2 somevalue2
   % ... (more key:value pairs)
>>
stream
% Here is the content of the object stream
endstream
endobj
 

«Поток изображений» имеет в основном ту же структуру. Но пары ключ: значение обычно содержат следующие четыре записи в любом порядке (где NNN и MMM — целочисленные значения, задающие ширину и высоту изображения в пикселях):

 /Type /XObject
/Subtype /Image
/Width NNN
/Height MMM
 

Обновление / исправление

Мой плохой! Мой первоначальный ответ содержал повторяющуюся опечатку. Я использовал tj в тех местах, где Tj должен был использоваться. Извините за любую путаницу, которая могла возникнуть.

Комментарии:

1. На самом деле — это работало только для одного файла, создавая искаженный вывод для других. Изменение TJ s на JT s (или любую комбинацию) привело к тому же результату и для этих файлов — в какой-то момент вывод будет просто искажен. В итоге я нашел все вхождения nBTn и nETn и удалил все между ними.

2. @eithedog: Если я не могу просмотреть сам файл, я не могу проанализировать, почему вы сталкиваетесь с тем поведением, которое вы наблюдаете. Единственное, что (на мой взгляд) может оказать влияние ' , " — это операторы and: они также используются для «отображения текста» , аналогично Tj and TJ (но с некоторыми дополнительными изменениями, такими как автоматический переход к следующей строке или установка расстояний между словами).

3. Я понимаю это и ценю помощь. Может быть, tj это действительно может встречаться в потоках изображений, и именно поэтому их изменение приведет к искажению выводимого PDF-файла? Как я уже упоминал — в конце я просто удалил все между BT и ET , и это, казалось, помогло. Я предположил, что это был декодированный текстовый поток со всеми преобразованиями — поскольку он также содержал tj s — например: Td[(C)7(arr)3(ot C)7(ak)8(e......Ł2)]TJ , но это также: Tm (DRINKS)Tj

4. @eithedog: «Может ли быть так, что tj действительно можно встретить в потоках изображений, и именно поэтому …» . Да. Будьте осторожны, когда вы меняете строки TJ и Tj : только внутри «потоков объектов PDF» (как я говорю в своем ответе), никогда глобально по всему файлу PDF (где он может соответствовать потоку изображений)…

Ответ №3:

Очевидно, что это не стандартное требование, но недавно оно обсуждалось на форуме #Ghostscript в IRC. Канал зарегистрирован, и вы можете найти обсуждение здесь:

http://ghostscript.com/irclogs/2014/05/21.html

Первоначально мы предлагали изменить начальный режим рендеринга текста на 3 дюйма pdf_ops.ps , но это никак не повлияло на файл, так как в нем использовался шрифт type 3. Поэтому мы предложили вместо этого изменить определения TJ и Tj в одном файле. Посмотрите в журнале примерно на 15:37.

Комментарии:

1. В pdf_ops.ps , измените определения /TJ и /Tj, в каждом случае замените ‘Show’ на ‘pop’. В зависимости от вашей операционной системы и того, как был создан Ghostscript, вам может потребоваться перестроить Ghostscript или включить каталог, содержащий измененные файлы, введя -I<имя каталога> в командной строке

2. Могу ли я это сделать, если я уже установил GS на OS X? Я не могу найти pdf_ops.ps на жестком диске. Теперь я также загрузил исходный код GS и нашел этот файл и определения /TJ, Tj. Я думаю, мне нужно перестроить его, когда я их изменю? И какую команду мне нужно выполнить, чтобы удалить текст из файла PDF после того, как я внесу эти изменения /TJ, / Tj?

3. Ghostscript может быть создан многими способами… Если вы создаете с помощью COMPILE_INITS=1, то файлы поддержки будут встроены в исполняемый файл. Если вы создаете с помощью COMPILE_INITS=0, то они находятся на диске. В любом случае вы можете использовать переключатель -I (включить), чтобы указать Ghostscript сначала искать файлы в каталоге или списке каталогов. Таким образом, вы можете поместить измененный gs / Resource / Init где-нибудь, изменить pdf_ops.ps а затем скажите GS, чтобы он использовал этот каталог. Затем вы используете устройство pdfwrite для создания нового файла PDF (оригинал остается нетронутым), поскольку текстовые операторы не работают, в новом файле нет текста.

4. Упс, поскольку вы выполняете рендеринг в формате PNG, просто используйте любую командную строку, которую вы уже используете, опять же, поскольку операторы TJ и Tj не являются операторами, текст не будет отображаться.

5. Хорошо, спасибо, надеюсь, я смогу это сделать! Я никогда не создавал GS самостоятельно, я просто использовал установщик OS X для его установки в системе. Я попытаюсь с помощью переключателя -l указать на измененные файлы ресурсов.