问题:给定一个PDF文件,我可以(很容易)使用PDFsharp (或另一个.NET兼容的PDF库)检查重叠的文本吗?
首选的解决方案是检查重叠字母(两个不同的文本块),但只检查重叠边界框的解决方案也是可以接受的。
我已经尝试过的:一个明显的解决方案是提取所有文本组件的边界框,并检查这些内容是否重叠。但是,我没有在PDFsharp中找到一种方法来提取带有边界框的文本组件。对于避免XY问题,我问的是一般的问题,而不是如何用PDFsharp提取文本。
背景:我正在为我们的报告组件编写单元测试。报告生成为PDF文件,使用RDLC报告的PDF呈现组件以及直接使用PdfSharp的PDF输出。
在我的单元测试中,我希望使用不同的数据集和语言来测试这些报告,并找出是否有重叠的文本。目前,单元测试只是为我想测试的每一个组合导出PDF,并且必须有人手动查看它们。我想把它自动化。
发布于 2016-06-02 09:37:56
下面的代码展示了如何使用XFINIUM.PDF库实现此检测(因为您询问了包括其他库在内的解决方案):
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;
}关于代码的几个注意事项:
免责声明:我为开发XFINIUM.PDF库的公司工作。
https://stackoverflow.com/questions/37571694
复制相似问题