使用 LocationTextLocationStrategy 的 iText "Coordinate outside allowed range" 异常
iText "Coordinate outside allowed range" exception using LocationTextLocationStrategy
当我尝试使用 LocationTextExtractionStrategy
时抛出异常 "Coordinate outside allowed range"。
for (int pageNum = 1; pageNum <= document.getNumberOfPages(); pageNum++)
{
PdfPage page = document.getPage(pageNum);
sb.append(PdfTextExtractor.getTextFromPage(page, new LocationTextExtractionStrategy()));
}
有关异常的更多信息:
java.lang.IllegalStateException: Coordinate outside allowed range
at com.itextpdf.kernel.pdf.canvas.parser.clipper.ClipperBase.rangeTest(ClipperBase.java:76)
我有 2 个由同一个软件生成的类似 PDF,第一个抛出异常,第二个没有。
什么在第一个 PDF 中引发此异常?如何在不使用 SimpleTextExtractionStrategy 的情况下解决这个问题?
(根据您的堆栈跟踪,您使用的是 iText 7.* 版本。我相应地更新了您的问题标签,并使用当前的 iText 7.1.2-SNAPSHOT 重现了该问题。)
什么在第一个 PDF 中引发此异常?
简而言之
您的两个 PDF 都包含用于定义剪辑路径的极端 y 坐标(超出 ISO 32000-1 实施限制),您的 PDF 1 仅是 PDF 2 和 iText 剪辑的两倍路径例程在两者之间的某个地方开始打嗝。
详细
PDF 1 第 1 页的页面内容流基本上如下所示:
q
[...]
% modifyCTM
0.802969 0 0 -0.802969 0 842 cm
[...]
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
Q
因此,即使考虑到 CTM 的初始修改,您也六次定义了高度为 98417 * 0.802969
默认用户单位的剪辑路径矩形,该高度大约等于 79026
默认用户单位。
ISO 32000-1 Annex C.2 架构限制 另一方面表明
conforming readers should accommodate PDF files that obey the constraints.
[...]
- The minimum page size should be 3 by 3 units in default user space; the maximum should be 14,400 by 14,400 units.
因此,您的剪辑路径矩形是符合要求的 reader 预期支持的页面高度的五倍多。因此,符合要求的 reader 不需要支持您的极端剪辑路径。
PDF 2 的构建方式类似,所讨论的剪辑路径只有 41879 * 0.802969
个单位高,即大约 33628
个单位,这只是需要支持的两倍多。由于某些原因,iText 似乎仍然支持这一点。
如何在不使用 SimpleTextExtractionStrategy 的情况下解决这个问题?
您可以通过更改常量来调整 iText 7 com.itextpdf.kernel.pdf.canvas.parser.clipper.ClipperBridge.floatMultiplier
/**
* Since the clipper library uses integer coordinates, we should convert
* our floating point numbers into fixed point numbers by multiplying by
* this coefficient. Vary it to adjust the preciseness of the calculations.
*/
public static double floatMultiplier = Math.pow(10, 14);
你可以试试Math.pow(10, 10)
这对我适用于你的两个文件。
也就是说,ISO 32000-2 似乎已经放弃了这个特定的页面大小限制,只是有更通用的限制加上声明,例如特定设备上的 特定 PDF 处理器 运行而且在特定的运行环境下总会有实际的限制。
因此,@iText 应该考虑当前的限制是实际限制还是应该放宽。
当我尝试使用 LocationTextExtractionStrategy
时抛出异常 "Coordinate outside allowed range"。
for (int pageNum = 1; pageNum <= document.getNumberOfPages(); pageNum++)
{
PdfPage page = document.getPage(pageNum);
sb.append(PdfTextExtractor.getTextFromPage(page, new LocationTextExtractionStrategy()));
}
有关异常的更多信息:
java.lang.IllegalStateException: Coordinate outside allowed range
at com.itextpdf.kernel.pdf.canvas.parser.clipper.ClipperBase.rangeTest(ClipperBase.java:76)
我有 2 个由同一个软件生成的类似 PDF,第一个抛出异常,第二个没有。
什么在第一个 PDF 中引发此异常?如何在不使用 SimpleTextExtractionStrategy 的情况下解决这个问题?
(根据您的堆栈跟踪,您使用的是 iText 7.* 版本。我相应地更新了您的问题标签,并使用当前的 iText 7.1.2-SNAPSHOT 重现了该问题。)
什么在第一个 PDF 中引发此异常?
简而言之
您的两个 PDF 都包含用于定义剪辑路径的极端 y 坐标(超出 ISO 32000-1 实施限制),您的 PDF 1 仅是 PDF 2 和 iText 剪辑的两倍路径例程在两者之间的某个地方开始打嗝。
详细
PDF 1 第 1 页的页面内容流基本上如下所示:
q
[...]
% modifyCTM
0.802969 0 0 -0.802969 0 842 cm
[...]
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
Q
因此,即使考虑到 CTM 的初始修改,您也六次定义了高度为 98417 * 0.802969
默认用户单位的剪辑路径矩形,该高度大约等于 79026
默认用户单位。
ISO 32000-1 Annex C.2 架构限制 另一方面表明
conforming readers should accommodate PDF files that obey the constraints.
[...]
- The minimum page size should be 3 by 3 units in default user space; the maximum should be 14,400 by 14,400 units.
因此,您的剪辑路径矩形是符合要求的 reader 预期支持的页面高度的五倍多。因此,符合要求的 reader 不需要支持您的极端剪辑路径。
PDF 2 的构建方式类似,所讨论的剪辑路径只有 41879 * 0.802969
个单位高,即大约 33628
个单位,这只是需要支持的两倍多。由于某些原因,iText 似乎仍然支持这一点。
如何在不使用 SimpleTextExtractionStrategy 的情况下解决这个问题?
您可以通过更改常量来调整 iText 7 com.itextpdf.kernel.pdf.canvas.parser.clipper.ClipperBridge.floatMultiplier
/**
* Since the clipper library uses integer coordinates, we should convert
* our floating point numbers into fixed point numbers by multiplying by
* this coefficient. Vary it to adjust the preciseness of the calculations.
*/
public static double floatMultiplier = Math.pow(10, 14);
你可以试试Math.pow(10, 10)
这对我适用于你的两个文件。
也就是说,ISO 32000-2 似乎已经放弃了这个特定的页面大小限制,只是有更通用的限制加上声明,例如特定设备上的 特定 PDF 处理器 运行而且在特定的运行环境下总会有实际的限制。
因此,@iText 应该考虑当前的限制是实际限制还是应该放宽。