gpt4 book ai didi

java - 如何使用pdfbox检查文本是否透明

转载 作者:行者123 更新时间:2023-12-01 18:41:31 26 4
gpt4 key购买 nike

我子类化了 PDFStreamEngine 并重载了 processTextPosition,我现在能够像 PDFTextStripper 一样重建文本,但我不想处理透明文本,通常是垃圾。

我如何知道某些文本是否透明?

最佳答案

事实证明,透明文本实际上根本不透明,而只是被图像覆盖:在 201103 Key Smoking Statistic for SA 2010 FINAL.pdf 中文本“SA --- 2004 年主要吸烟统计数据”已被显示 TC Logo 的图像覆盖。

下面显示了文本剥离器类的概念证明,该类忽略图像覆盖的文本。

public class VisibleTextStripper extends PDFTextStripper
{
public VisibleTextStripper() throws IOException
{
super();
registerOperatorProcessor("Do", new Invoke());
}

//
// Hiding operations
//
void hide(String name)
{
Matrix ctm = getGraphicsState().getCurrentTransformationMatrix();
float x = ctm.getXPosition();
float y = ctm.getYPosition();
float scaledWidth = ctm.getXScale();
float scaledHeight = ctm.getYScale();

for(List<TextPosition> characters : charactersByArticle)
{
Collection<TextPosition> toRemove = new ArrayList<TextPosition>();
for (TextPosition character : characters)
{
Matrix matrix = character.getTextPos();
float cx = matrix.getXPosition();
float cy = matrix.getYPosition();
float cw = character.getWidth();
float ch = character.getHeight();
if (overlaps(x, scaledWidth, cx, cw) && overlaps(y, scaledHeight, cy, cw))
{
System.out.printf("Hidden by '%s': X: %f; Y: %f; Width: %f; Height: %f; Char: '%s'\n", name, cx, cy, cw, ch, character.getCharacter());
toRemove.add(character);
}
}
characters.removeAll(toRemove);
}
}

private boolean overlaps(float start1, float width1, float start2, float width2)
{
if (width1 < 0)
{
start1 += width1;
width1 = -width1;
}

if (width2 < 0)
{
start2 += width2;
width2 = -width2;
}

if (start1 < start2)
{
return start1 + width1 >= start2;
}
else
{
return start2 + width2 >= start1;
}
}

//
// operator processors
//
public static class Invoke extends OperatorProcessor
{
/**
* Log instance.
*/
private static final Log LOG = LogFactory.getLog(Invoke.class);

/**
* process : Do : Paint the specified XObject (section 4.7).
* @param operator The operator that is being executed.
* @param arguments List
* @throws IOException If there is an error invoking the sub object.
*/
public void process(PDFOperator operator, List<COSBase> arguments) throws IOException
{
VisibleTextStripper drawer = (VisibleTextStripper)context;
COSName objectName = (COSName)arguments.get( 0 );
Map<String, PDXObject> xobjects = drawer.getResources().getXObjects();
PDXObject xobject = (PDXObject)xobjects.get( objectName.getName() );
if ( xobject == null )
{
LOG.warn("Can't find the XObject for '"+objectName.getName()+"'");
}
else if( xobject instanceof PDXObjectImage )
{
drawer.hide(objectName.getName());
}
else if(xobject instanceof PDXObjectForm)
{
PDXObjectForm form = (PDXObjectForm)xobject;
COSStream formContentstream = form.getCOSStream();
// if there is an optional form matrix, we have to map the form space to the user space
Matrix matrix = form.getMatrix();
if (matrix != null)
{
Matrix xobjectCTM = matrix.multiply( context.getGraphicsState().getCurrentTransformationMatrix());
context.getGraphicsState().setCurrentTransformationMatrix(xobjectCTM);
}
// find some optional resources, instead of using the current resources
PDResources pdResources = form.getResources();
context.processSubStream( context.getCurrentPage(), pdResources, formContentstream );
}
}
}
}

它与您的示例文档配合良好。

支票

if (overlaps(x, scaledWidth, cx, cw) && overlaps(y, scaledHeight, cy, cw))

不幸的是,假设不涉及旋转(所有转换聚合),无论是文本还是图像。

对于通用解决方案,您必须将此测试更改为检查由 Matrix ctm = getGraphicsState().getCurrentTransformationMatrix() 转换的 1x1 正方形是否与由 转换的字符框重叠>矩阵matrix = character.getTextPos(),具有固定的宽度和高度cw =character.getWidth()ch=character.getHeight()。也许简单的重叠还不够,您可能希望字符框被充分覆盖。

此外,此测试忽略图像蒙版,即图像的透明度。

关于java - 如何使用pdfbox检查文本是否透明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19809813/

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