如何将文本 pdf 更改为 utf-8 编码?

How to change a texted pdf to utf-8 encoding?

我有一堆可以正确显示西里尔文的 pdf。但是如果我从他们那里复制和粘贴文本,就会产生乱码。

然后我使用okular的另存为功能将pdf转换为文本文件,发现编码是WINDOWS-1251,这是一个旧的西里尔编码。转换为UTF-8后,西里尔字母可以正常显示了。

文件的样本 link 是 https://cdn.esis.edu.mn/cover/01/01_mongol_khel.pdf

有没有办法将 pdf 转换为 UTF-8 编码以便我可以复制、粘贴和搜索?


已解决:

根据@iPDFdev提供的信息,我设法解决了这个问题。

对于可能遇到类似问题的任何人,我在 https://www.compart.com/en/unicode/charsets/windows-1251, and modified the code at https://github.com/pymupdf/PyMuPDF/issues/530 处将 Windows-1251 转为 UTF-8 table。我完全忽略了旧的 Unicode 映射,并为所有页面上的所有字体添加了西里尔字母映射。

import fitz
import re
doc = fitz.open(inputFileName)
new = '1 beginbfrange\n<c0> <ff> <0410>\nendbfrange'
for pno in range(doc.page_count):
    font_tuples = doc.get_page_fonts(2) 
    for font_tuple in font_tuples:
        for line in doc.xref_object(font_tuple[0]).splitlines():
            line = line.strip()
            if line.startswith("/ToUnicode"):
                stream_id = int(line.split()[1])
                old_stream_decoded = doc.xref_stream(stream_id).decode()
                new_stream_decoded = re.sub('[0-9]+? beginbfrange.*endbfrange', new, old_stream_decoded, flags=re.DOTALL)
                new_stream_encoded = new_stream_decoded.encode()
                doc.update_stream(stream_id, new_stream_encoded)
doc.save(outputFileName)

可以使用 Windows 1251 编码将 CID(字符 ID)正确(手动)转换为西里尔文。
但是 PDF 不支持这种编码,并且字体上的 ToUnicode cmap 构建不正确。当它应该使用 Unicode 值时,它还假定 Windows-1251 编码。

例如:CID 0xCC用于显示西里尔大写字母EM(U+041C)。内部字体编码将 0xCC 映射到表示 U+041C 的字形(字符图像),因此在视觉上您可以得到正确的字母。
但是对于文本提取,您必须提供一个 ToUnicode cmap,它告诉每个 id 代表什么 Unicode 字符。所以 ToUnicode cmap 应该包含这样的条目 0xCC -> U+041C 但文件中的 ToUnicode cmap 包含此条目 0xCC -> U+00CC 这不是西里尔大写字母 EM.
顺便说一句,0xCC 使用 Windows 1251 编码映射到 U+041C,但 PDF 处理器无法知道这一点。

正在使用

poppler-22.04.0\Library\bin>pdftotext -layout -f 1 -l 1 -enc ISO-8859-9 encoded.pdf -

响应,仅布局的第一页尝试似乎表明存在一些编码问题,但它是一个粗略的程序输出,也许可以通过 FnR 或代码调整来改进

          Ш.Оунццг, Є.Хадаа,
          Д.Цогзолмаа, Т.нхтуяа




 МОНГОЛ ХЛ
                   I
      Еєнхий боловсолын сугуулийн
       1 дїг ангийн суах бичиг

Боловсол, ол, Шинжлх Ухаан, отын амны
           зєвшєєлєє хвлв.

            Долоо дах хвлл




    УГУУЛИЙН НОМЫН АНД ОЛГОВ.
     БОЛУУЛАХЫГ ХОИГЛОНО.

             Улаанбаата хот
                 2020 он

备选方案是尝试将此作为更有效的字符,但需要“de-spacing”

pdftotext -layout -f 1 -l 1 -enc UTF-16 encoded.pdf -

                         Ш . О ю у н ц э ц э г ,   Є . Х а д а а ,
                         Д . Ц о г з о л м а а ,   Т . Э н х т у я а




   М О Н Г О Л   Х Э Л
                                           I
               Е р є н х и й   б о л о в с р о л ы н   с у р г у у л и й н
                   1   д ї г э э р   а н г и й н   с у р а х   б и ч и г

 Б о л о в с р о л ,  ! оQ л ,   Ш и н ж л э х   У х а а н ,  !? о р т ы н   / а м н ы
                           з є в ш є є р л є є р   х э в л э в .

                             Д о л о о   д а хL   х э в л э л




          ! У Р Г У У Л И Й Н   Н О М Ы Н  ! А Н Д   О Л Г О В .
                 Б О Р Л У У Л А Х Ы Г   Х О Р И Г Л О Н О .

                               У л а а н б а а т а р   х о т
                                       2 0 2 0   о н

De-spaced 但仍然需要将 �! 替换为 C 并将 �/ 替换为 Я

注意两种情况下 chcp 1251