尝试从pdf中提取字形ID时,某些字形ID丢失

时间:2018-06-03 07:23:40

标签: java pdf pdfbox

由于Devanagiri字形映射到unicode字符不正确,我使用以下代码提取字形ID并形成我自己的映射以将ID映射到正确的unicode字符。

public class ExtractCharacterCodes {
public static void testExtractFromSingNepChar() throws IOException {
    PDDocument document = PDDocument.load(new File("C:/PageSeparator/pattern3.pdf"));
    PDFTextStripper stripper = new PDFTextStripper() {
        @Override
        protected void writeString(String text, List<TextPosition> textPositions) throws IOException {
            for (TextPosition textPosition : textPositions) {
                writeString(String.format("%s%s", textPosition.getUnicode(), Arrays.toString(textPosition.getCharacterCodes())));
            }
        }
    };
    //stripper.setSortByPosition(true);
    String text = stripper.getText(document);

    System.out.printf("\n*\n* singNepChar.pdf\n*\n%s\n", text);
}

public static void main(String[] args) throws IOException {
    ExtractCharacterCodes.testExtractFromSingNepChar();
}

}

适用于此pdf Nepali pdf

我得到以下内容:स[1434]नु[1418] [3]त[1414]स्[7021]क[1399]र[1426]ी[1440]क[1399]ा[1438] [3]म[1424]खु्[6990]य[1425] [3]अ[1383]ा[4285]ा[1438]र[1426]ो[1451]प[1420]ी[1440] [3]'[39]ग[1401]ो[1451]रे[1426]'[39] [32] क[1399]ा[1438]ठ[1410]म[1424]ा[1438]ड[1411]ौं[7301]क[1399]ो[1451] [3]ग[1401]ौ[1452]र[1426]ी[1440]घ[1402]ा[1438]ट[1409]ब[1422]ा[1438]ट[1409] [3]प[1420]क्र[7059]ा[1438]उ[1387] [32] ज[1406]न[1418]क[1399]र[1426]ा[1438]ज[1406] [3]स[1434]ा[1438]प[1420]क[1399]ो[1451]ट[1409]ा[1438]त[1414]स्[1439]स्[7021]ब[1422]र[1426] [3]:[29] [3]क[1399]स्[1439]ि[1431]न[1418] [3]अ[1383]स्[1439]ध[1417]क[1399]ा[1438]र[1426]ी[1440] [32]|[124] [32]ज[1406]े[1447]ष्ठ[7399] [3] ८[1481],[44] [32]२[1475]०[1473]७[1480]५[1478] [32]依此类推

你可以看到我有一个字符串“सुन”被分隔为[1434],नु[1418]。我开始将自己的字形ID地图制作为字符,但在这种情况下,缺少字形ID。它sh [1434],न[1441],ु[1418]。我怎么得到这个?

1 个答案:

答案 0 :(得分:1)

原因是PDFTextStripper不仅将它从底层解析器检索的TextPosition对象组织成行并添加隐含空格,它还会在转发到{{{{}}之前对它们进行一些额外的预处理。 1}}。特别是它

  • 抑制重复的重叠字形:创建一个穷人的大胆效果的一种方法是用微小的偏移绘制两次字形,并且这些副本被抑制;而它
  • 将包含变音符号的writeString对象与包含相应基本字形的TextPosition合并到表示组合Unicode代码点的TextPosition

可以使用TextPosition禁用前一个处理步骤,但后者不能。

您观察到的效果是由后一个处理步骤引起的。

如果你想获得没有任何预处理的字形,即没有重复抑制和变音符合并但没有将它们组织成行并添加隐含空格,你可以覆盖{{1}而不是PDFTextStripper.setSuppressDuplicateOverlappingText(false)

processTextPosition

ExtractCharacterCodes test writeString

现在,您的示例文档的结果是

PDDocument document = PDDocument.load(resource);
PDFTextStripper stripper = new PDFTextStripper() {
    @Override
    protected void processTextPosition(TextPosition textPosition) {
        try {
            writeString(String.format("%s%s", textPosition.getUnicode(), Arrays.toString(textPosition.getCharacterCodes())));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
};

String text = stripper.getText(document);

如果您仍然希望testExtractFromPattern3将字形组织成行并添加隐含空格,则必须修补该类(或您自己的副本)并在其स[1434]ु[1441]न[1418] [3]त[1414]स्[7021]क[1399]र[1426]ी[1440]क[1399]ा[1438] [3]... 的末尾实现通过替换

来禁用变音符合并
PDFTextStripper

简单

processTextPosition

顺便说一句,您的测试文件在PDFBox确定基本字形中暴露了错误,以便将变音符号合并为:“स[1434]ー[1441]न[1418]”意图呈现为“सुन” “,即元音符号”ु“与字母”स“结合,但PDFBox将其与随后的字母”न“结合为”सनु“。

原因在于它确定了将变音符号与其原点结合起来的字母,其实际上在后一个字母na“न”的范围内,但是因为元音符号字形在其原点之前呈现 / em>(它在负 x 坐标的区域中绘制),PDFBox确定错误的关联:

SA-U-NA