首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PDFsharp能帮我发现重叠的文本吗?

PDFsharp能帮我发现重叠的文本吗?
EN

Stack Overflow用户
提问于 2016-06-01 14:34:30
回答 1查看 719关注 0票数 0

问题:给定一个PDF文件,我可以(很容易)使用PDFsharp (或另一个.NET兼容的PDF库)检查重叠的文本吗?

首选的解决方案是检查重叠字母(两个不同的文本块),但只检查重叠边界框的解决方案也是可以接受的。

我已经尝试过的:一个明显的解决方案是提取所有文本组件的边界框,并检查这些内容是否重叠。但是,我没有在PDFsharp中找到一种方法来提取带有边界框的文本组件。对于避免XY问题,我问的是一般的问题,而不是如何用PDFsharp提取文本。

背景:我正在为我们的报告组件编写单元测试。报告生成为PDF文件,使用RDLC报告的PDF呈现组件以及直接使用PdfSharp的PDF输出。

在我的单元测试中,我希望使用不同的数据集和语言来测试这些报告,并找出是否有重叠的文本。目前,单元测试只是为我想测试的每一个组合导出PDF,并且必须有人手动查看它们。我想把它自动化。

EN

回答 1

Stack Overflow用户

发布于 2016-06-02 09:37:56

下面的代码展示了如何使用XFINIUM.PDF库实现此检测(因为您询问了包括其他库在内的解决方案):

代码语言:javascript
复制
public void TestCharacterOverlap()
{
    PdfFixedDocument document = new PdfFixedDocument("sample.pdf");

    for (int i = 0; i < document.Pages.Count; i++)
    {
        List<PdfVisualRectangle[]> overlaps = GetPageOverlaps(document.Pages[i]);
        if (overlaps.Count > 0)
        {
            // We have character overlapping.
        }
    }
}

public List<PdfVisualRectangle[]> GetPageOverlaps(PdfPage page)
{
    List<PdfVisualRectangle[]> overlaps = new List<PdfVisualRectangle[]>();

    PdfContentExtractor ce = new PdfContentExtractor(page);
    PdfTextFragmentCollection tfc = ce.ExtractTextFragments();

    for (int i = 0; i < tfc.Count; i++)
    {
        PdfTextGlyphCollection currentGlyphs = tfc[i].Glyphs;

        for (int j = 0; j < currentGlyphs.Count; j++)
        {
            // Start comparing current glyph to remaining extracted glyphs.
            for (int k = i; k < tfc.Count; k++)
            {
                PdfTextGlyphCollection nextGlyphs = tfc[k].Glyphs;
                // l = j + 1 - we avoid comparing current glyph with itself
                for (int l = j + 1; l < nextGlyphs.Count; l++)
                {
                    PdfVisualRectangle crtGlyphRect = GetGlyphRectangle(currentGlyphs[j].GlyphCorners);
                    PdfVisualRectangle nextGlyphRect = GetGlyphRectangle(nextGlyphs[l].GlyphCorners);
                    if (Intersect(crtGlyphRect, nextGlyphRect))
                    {
                        PdfVisualRectangle[] overlap = new PdfVisualRectangle[] { crtGlyphRect, nextGlyphRect };
                        overlaps.Add(overlap);
                    }
                }
            }
        }
    }

    return overlaps;
}

public PdfVisualRectangle GetGlyphRectangle(PdfPoint[] glyphCorners)
{
    double minX = Math.Min(Math.Min(glyphCorners[0].X, glyphCorners[1].X), Math.Min(glyphCorners[2].X, glyphCorners[3].X));
    double minY = Math.Min(Math.Min(glyphCorners[0].Y, glyphCorners[1].Y), Math.Min(glyphCorners[2].Y, glyphCorners[3].Y));
    double maxX = Math.Max(Math.Max(glyphCorners[0].X, glyphCorners[1].X), Math.Max(glyphCorners[2].X, glyphCorners[3].X));
    double maxY = Math.Max(Math.Max(glyphCorners[0].Y, glyphCorners[1].Y), Math.Max(glyphCorners[2].Y, glyphCorners[3].Y));

    return new PdfVisualRectangle(minX, minY, maxX - minX, maxY - minY);
}

public bool Intersect(PdfVisualRectangle rc1, PdfVisualRectangle rc2)
{
    bool intersect = (rc1.Left < rc2.Left + rc2.Width) && (rc1.Left + rc1.Width > rc2.Left) &&
        (rc1.Top < rc2.Top + rc2.Height) && (rc1.Top + rc1.Height > rc2.Top);

    return intersect;
}

关于代码的几个注意事项:

  • 在大多数情况下(常规的水平文本),字形角(4个点)形成一个矩形。但是对于对角线文本或倾斜字符,字形角是一个四边形形状,因此您必须实现一个更复杂的相交过程。
  • 重叠测试可以进一步抛光,以允许小程度的重叠,如果交集大于字符面积的X%,我们假设有2个字符重叠。这就是为什么GetPageOverlaps方法返回成对矩形的集合,以便在需要时进一步处理它们。

免责声明:我为开发XFINIUM.PDF库的公司工作。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37571694

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档