Используйте PyPDF2 для обнаружения не встроенных шрифтов в файле PDF, созданном в Документах Google. - PullRequest
1 голос
/ 27 марта 2020

Я надеялся, что кто-нибудь может помочь мне написать функцию Python для обнаружения любых шрифтов в файле, которые не встроены в файл. Я попытался использовать скрипт, связанный с здесь , и он может обнаружить шрифты документов, но не обнаруживает встроенные шрифты. Для удобства я вставил приведенный ниже сценарий:

from PyPDF2 import PdfFileReader
import sys

fontkeys = set(['/FontFile', '/FontFile2', '/FontFile3'])

def walk(obj, fnt, emb):
    if '/BaseFont' in obj:
        fnt.add(obj['/BaseFont'])

    elif '/FontName' in obj and fontkeys.intersection(set(obj)):
        emb.add(obj['/FontName'])

    for k in obj:
        if hasattr(obj[k], 'keys'):
            walk(obj[k], fnt, emb)

    return fnt, emb

if __name__ == '__main__':
    fname = sys.argv[1]
    pdf = PdfFileReader(fname)
    fonts = set()
    embedded = set()

    for page in pdf.pages:
        obj = page.getObject()
        f, e = walk(obj['/Resources'], fonts, embedded)
        fonts = fonts.union(f)
        embedded = embedded.union(e)

    unembedded = fonts - embedded
    print 'Font List'
    pprint(sorted(list(fonts)))
    if unembedded:
        print '\nUnembedded Fonts'
        pprint(unembedded)

Например, я скачал PDF-файл из Google Docs (введите некоторые данные, сохраните как PDF) шрифтом Arial, и Adobe Reader подтвердил что шрифт встроен. Однако скрипт возвращает ['/ ArialMT'] в качестве шрифта и пустой набор для встроенных шрифтов. Кроме того, похоже, что ни один из рекурсивных объектов не имеет ключей {'/FontFile', '/FontFile2', '/FontFile3'}. Я пробовал это на других PDF-файлах, и это работает, так что это должно быть что-то странное с PDF-файлами Google Docs. Дайте мне знать, какую другую отладочную информацию я могу предоставить для этого файла PDF.

Adobe confirming that the font is embedded

Одна вещь, которую я подумал, заключалась в том, что в Документах Google было возможно встраивать только те шрифты, которые отсутствовали в 14 стандартных шрифтах PDF. Тем не менее, я попробовал это со странным шрифтом (pacifico), и сценарий также заявил, что этот шрифт не был встроен, когда Adobe утверждает, что это так. Pacifico being embedded, script saying its not

Я пробовал с этим PDF , и скрипт правильно указал, что эти 14 шрифтов были встроены.

1 Ответ

0 голосов
/ 28 марта 2020

Проблема в том, что этот скрипт не обрабатывает списки. Например, в примере Документов Google, в объекте PDF вы видите следующую структуру:

{'/Encoding': '/Identity-H', '/Type': '/Font', '/BaseFont': '/Pacifico-Regular', '/ToUnicode': IndirectObject(9, 0), '/DescendantFonts': [IndirectObject(16, 0)], '/Subtype': '/Type0'}

Ключ DescendantFonts отображается в список значений, который, если вы углубитесь в глубину, будет содержать ключи для файлы шрифтов. Вы также должны изменить скрипт для проверки массивов, например:

if type(obj) == PyPDF2.generic.ArrayObject:  # You can also do ducktyping here
    for i in obj:
        if hasattr(i, 'keys'):
            walk(i, all_fonts, embedded_fonts)
...