gpt4 book ai didi

java - PDFClown 一行中不同字体大小

转载 作者:行者123 更新时间:2023-12-02 12:28:00 25 4
gpt4 key购买 nike

我正在使用 PDFClown 来分析 PDF 文档。在许多文档中,PDFClown 中的某些字符似乎具有不同的高度,即使它们显然具有相同的高度。有解决办法吗?

这是代码:

    while(_level.moveNext()) {
ContentObject content = _level.getCurrent();
if(content instanceof Text) {
ContentScanner.TextWrapper text = (ContentScanner.TextWrapper)_level.getCurrentWrapper();
for(ContentScanner.TextStringWrapper textString : text.getTextStrings()) {
List<CharInfo> chars = new ArrayList<>();
for(TextChar textChar : textString.getTextChars()) {
chars.add(new CharInfo(textChar.getBox(), textChar.getValue()));
}
}
}
else if(content instanceof XObject) {
// Scan the external level
if(((XObject)content).getScanner(_level)!=null){
getContentLines(((XObject)content).getScanner(_level));
}
}
else if(content instanceof ContainerObject){
// Scan the inner level
if(_level.getChildLevel()!=null){
getContentLines(_level.getChildLevel());
}
}
}

这是一个 PDF 文档示例:

Example

在本文档中,我标记了两个文本 block ,它们都包含单词“million”。当分析两个“百万”中每个字符的大小时,会发生以下情况:

  1. 第一个标记中的“m”高度:14,50,宽度:8,5
  2. 第一个标记中的“i”高度:14,50,宽度:3,0
  3. 第一个标记中的“l”高度为:14,50,宽度为3,0
  4. 第二个标记中的“m”高度:10,56,宽度:6,255
  5. 第二个标记中的“i”高度:10,56,宽度:2,23
  6. 第二个标记中的“l”高度:10,56,宽度:2,23

即使两个文本 block 的所有字符显然具有相同的大小,pdf clown 也会说大小不同。

最佳答案

该问题是由 PDF Clown 中的错误引起的:它假设标记的内容部分和保存/恢复图形状态 block 正确地相互包含并且不重叠。 IE。它假设这些结构仅混合为

begin-marked-content
save-graphics-state
restore-graphics-state
end-marked-content

save-graphics-state
begin-marked-content
end-marked-content
restore-graphics-state

但从未如此

save-graphics-state
begin-marked-content
restore-graphics-state
end-marked-content

begin-marked-content
save-graphics-state
end-marked-content
restore-graphics-state.

不幸的是,这个假设是错误的,标记的内容部分和保存/恢复图形状态 block 可以以任何它们喜欢的方式混合。

例如在手头的文档中有这样的序列:

q
[...1...]
/P <</MCID 0 >>BDC
Q
[...2...]
EMC

这里[...1...]包含在 q 包围的保存/恢复图形状态 block 中和Q[...2...]包含在 /P <</MCID 0 >>BDC 包围的标记内容 block 中和EMC .

但是,由于错误的假设,以及方式 /P <</MCID 0 >>BDCQ排列好后,PDF Clown 将上面的内容解析为 [...1...]和一个空的标记内容 block 和 [...2...]包含在保存/恢复图形状态 block 中。

因此,如果 [...2...] 内部的图形状态发生变化,PDF Clown 假设它们仅限于上面的行,但实际上并非如此。

<小时/>

我发现修复此问题的唯一简单方法是禁用 PDF Clown 中的标记内容解析。

为此,我更改了 org.pdfclown.documents.contents.tokens.ContentParser如下:

  1. parseContentObjects()我禁用了contentObject instanceof EndMarkedContent选项:

      public List<ContentObject> parseContentObjects(
    )
    {
    final List<ContentObject> contentObjects = new ArrayList<ContentObject>();
    while(moveNext())
    {
    ContentObject contentObject = parseContentObject();
    // Multiple-operation graphics object end?
    if(contentObject instanceof EndText // Text.
    || contentObject instanceof RestoreGraphicsState // Local graphics state.
    /* || contentObject instanceof EndMarkedContent // End marked-content sequence. */
    || contentObject instanceof EndInlineImage) // Inline image.
    return contentObjects;

    contentObjects.add(contentObject);
    }
    return contentObjects;
    }
  2. parseContentObject我删除了if(operation instanceof BeginMarkedContent)分支:

      public ContentObject parseContentObject(
    )
    {
    final Operation operation = parseOperation();
    if(operation instanceof PaintXObject) // External object.
    return new XObject((PaintXObject)operation);
    else if(operation instanceof PaintShading) // Shading.
    return new Shading((PaintShading)operation);
    else if(operation instanceof BeginSubpath
    || operation instanceof DrawRectangle) // Path.
    return parsePath(operation);
    else if(operation instanceof BeginText) // Text.
    return new Text(
    parseContentObjects()
    );
    else if(operation instanceof SaveGraphicsState) // Local graphics state.
    return new LocalGraphicsState(
    parseContentObjects()
    );
    /* else if(operation instanceof BeginMarkedContent) // Marked-content sequence.
    return new MarkedContent(
    (BeginMarkedContent)operation,
    parseContentObjects()
    );
    */ else if(operation instanceof BeginInlineImage) // Inline image.
    return parseInlineImage();
    else // Single operation.
    return operation;
    }

完成这些更改后,可以正确提取字符大小。

<小时/>

顺便说一句,虽然返回的单个字符框似乎暗示该框完全是针对相关字符自定义的,但事实并非如此:框的宽度仅是特定于字符的,高度是根据整体字体计算的属性(和当前字体大小),但不是特定于字符,参见。 org.pdfclown.documents.contents.fonts.Font方法getHeight(char) :

  /**
Gets the unscaled height of the given character.

@param textChar
Character whose height has to be calculated.
*/
public final double getHeight(
char textChar
)
{
/*
TODO: Calculate actual text height through glyph bounding box.
*/
if(textHeight == -1)
{textHeight = getAscent() - getDescent();}
return textHeight;
}

单个字符高度计算仍然是待办事项。

关于java - PDFClown 一行中不同字体大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45413682/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com