为什么 PDFBox return 图像尺寸为 0 x 0
Why does PDFBox return image dimension of size 0 x 0
为了找到 PDF 上图像的实际大小,我使用 PDFBox,并按照 this SO answer 中的描述进行操作。所以基本上我打电话给
// Computes the image actual location and dimensions
PrintImageLocations renderer = new PrintImageLocations();
for (int i = 0; i < pageLimit; ++i) {
PDPage page = pdf.getPage(i);
renderer.processPage(page);
}
并且 PrintImageLocations() 取自 this PDFBox code example。
然而,对于我用于测试的 PDF 文档(由 GPL Ghostscript 910 (ps2write) 从找到的图像 on Wikipedia 生成),报告的图像大小为 0 x 0(尽管可以导入 PDF到 Gimp 或 Libre Office Draw)。
所以我想知道我目前使用的代码是否可靠地查找图像尺寸,以及什么会导致它找不到正确的图像尺寸?
本次测试使用的PDFcan be found here
==========
编辑:
在 @Itai 评论之后,似乎 条件 if ("Do".equals(operation))
未被评估 因为没有调用此类操作。因此调用超级 class 中的 processOperator
。
唯一调用的操作是(我在覆盖的 processOperator
方法中的条件之前添加了 System.err.println("Processing " + operation);
):
处理中
加工厘米
处理gs
加工质量
加工重新
处理W
加工次数
处理组
加工重新
处理 f
加工工艺
处理扫描
加工重新
处理 f
加工问
处理 Q
==========
感谢任何提示,
正如您自己已经发现的那样,输出 0x0 的原因是 PrintImageLocations
原样的代码根本找不到图像。
PrintImageLocations
找不到图像,因为它只查找页面内容中使用的图像以及页面内容中使用的 XObject(也嵌套)表单。另一方面,在手头的文件中,图像绘制在平铺 Pattern 内容中,用于 fill 页面中的区域内容。
为了让 PDFBox 找到这个图像,我们必须扩展 PrintImageLocations
class 一点,以便也下降到模式内容流中,例如像这样:
class PrintImageLocationsImproved extends PrintImageLocations {
public PrintImageLocationsImproved() throws IOException {
super();
addOperator(new SetNonStrokingColor());
addOperator(new SetNonStrokingColorN());
addOperator(new SetNonStrokingDeviceCMYKColor());
addOperator(new SetNonStrokingDeviceGrayColor());
addOperator(new SetNonStrokingDeviceRGBColor());
addOperator(new SetNonStrokingColorSpace());
}
@Override
protected void processOperator(Operator operator, List<COSBase> operands) throws IOException {
String operation = operator.getName();
if (fillOperations.contains(operation)) {
PDColor color = getGraphicsState().getNonStrokingColor();
PDAbstractPattern pattern = getResources().getPattern(color.getPatternName());
if (pattern instanceof PDTilingPattern) {
processTilingPattern((PDTilingPattern) pattern, null, null);
}
}
super.processOperator(operator, operands);
}
final List<String> fillOperations = Arrays.asList("f", "F", "f*", "b", "b*", "B", "B*");
}
(ExtractImageLocations内classPrintImageLocationsImproved
)
手头文档中的平铺图案用作填充而非描边的图案颜色。因此,PrintImageLocationsImproved
必须为非描边颜色运算符注册运算符侦听器,以便在图形状态中正确更新填充颜色。
processOperator
在委托给 PrintImageLocations
实现之前,现在首先检查运算符是否是 fill 操作。在这种情况下,它会检查当前的填充颜色。如果它是图案颜色,processOperator
启动 PDFStreamEngine
中定义的 processTilingPattern
处理,它开始对图案内容流进行嵌套分析,最终让 PrintImageLocationsImproved
找到图像.
像这样使用PrintImageLocationsImproved
try ( PDDocument document = PDDocument.load(...) )
{
PrintImageLocations printer = new PrintImageLocationsImproved();
int pageNum = 0;
for( PDPage page : document.getPages() )
{
pageNum++;
System.out.println( "Processing page: " + pageNum );
printer.processPage(page);
}
}
(ExtractImageLocations 测试 testExtractLikeHelloWorldImprovedFromTopSecret
)
因此,对于您的 PDF 文件,将找到图像:
Processing page: 1
*******************************************************************
Found image [R8]
position in PDF = 39.0, 102.48 in user space units
raw image size = 1209, 1640 in pixels
displayed size = 516.3119, 700.3752 in user space units
displayed size = 7.1709986, 9.727433 in inches at 72 dpi rendering
displayed size = 182.14336, 247.0768 in millimeters at 72 dpi rendering
小心,
这不是完美的修复,更多的是概念验证和解决方法,因为它既没有将图案正确限制到实际填充的区域,也没有 return 多次发现足够大的区域需要多个图案瓷砖来填充。尽管如此,它 return 是手头文件的图像匹配..
为了找到 PDF 上图像的实际大小,我使用 PDFBox,并按照 this SO answer 中的描述进行操作。所以基本上我打电话给
// Computes the image actual location and dimensions
PrintImageLocations renderer = new PrintImageLocations();
for (int i = 0; i < pageLimit; ++i) {
PDPage page = pdf.getPage(i);
renderer.processPage(page);
}
并且 PrintImageLocations() 取自 this PDFBox code example。
然而,对于我用于测试的 PDF 文档(由 GPL Ghostscript 910 (ps2write) 从找到的图像 on Wikipedia 生成),报告的图像大小为 0 x 0(尽管可以导入 PDF到 Gimp 或 Libre Office Draw)。
所以我想知道我目前使用的代码是否可靠地查找图像尺寸,以及什么会导致它找不到正确的图像尺寸?
本次测试使用的PDFcan be found here
==========
编辑:
在 @Itai 评论之后,似乎 条件 if ("Do".equals(operation))
未被评估 因为没有调用此类操作。因此调用超级 class 中的 processOperator
。
唯一调用的操作是(我在覆盖的 processOperator
方法中的条件之前添加了 System.err.println("Processing " + operation);
):
处理中 加工厘米 处理gs 加工质量 加工重新 处理W 加工次数 处理组 加工重新 处理 f 加工工艺 处理扫描 加工重新 处理 f 加工问 处理 Q
==========
感谢任何提示,
正如您自己已经发现的那样,输出 0x0 的原因是 PrintImageLocations
原样的代码根本找不到图像。
PrintImageLocations
找不到图像,因为它只查找页面内容中使用的图像以及页面内容中使用的 XObject(也嵌套)表单。另一方面,在手头的文件中,图像绘制在平铺 Pattern 内容中,用于 fill 页面中的区域内容。
为了让 PDFBox 找到这个图像,我们必须扩展 PrintImageLocations
class 一点,以便也下降到模式内容流中,例如像这样:
class PrintImageLocationsImproved extends PrintImageLocations {
public PrintImageLocationsImproved() throws IOException {
super();
addOperator(new SetNonStrokingColor());
addOperator(new SetNonStrokingColorN());
addOperator(new SetNonStrokingDeviceCMYKColor());
addOperator(new SetNonStrokingDeviceGrayColor());
addOperator(new SetNonStrokingDeviceRGBColor());
addOperator(new SetNonStrokingColorSpace());
}
@Override
protected void processOperator(Operator operator, List<COSBase> operands) throws IOException {
String operation = operator.getName();
if (fillOperations.contains(operation)) {
PDColor color = getGraphicsState().getNonStrokingColor();
PDAbstractPattern pattern = getResources().getPattern(color.getPatternName());
if (pattern instanceof PDTilingPattern) {
processTilingPattern((PDTilingPattern) pattern, null, null);
}
}
super.processOperator(operator, operands);
}
final List<String> fillOperations = Arrays.asList("f", "F", "f*", "b", "b*", "B", "B*");
}
(ExtractImageLocations内classPrintImageLocationsImproved
)
手头文档中的平铺图案用作填充而非描边的图案颜色。因此,PrintImageLocationsImproved
必须为非描边颜色运算符注册运算符侦听器,以便在图形状态中正确更新填充颜色。
processOperator
在委托给 PrintImageLocations
实现之前,现在首先检查运算符是否是 fill 操作。在这种情况下,它会检查当前的填充颜色。如果它是图案颜色,processOperator
启动 PDFStreamEngine
中定义的 processTilingPattern
处理,它开始对图案内容流进行嵌套分析,最终让 PrintImageLocationsImproved
找到图像.
像这样使用PrintImageLocationsImproved
try ( PDDocument document = PDDocument.load(...) )
{
PrintImageLocations printer = new PrintImageLocationsImproved();
int pageNum = 0;
for( PDPage page : document.getPages() )
{
pageNum++;
System.out.println( "Processing page: " + pageNum );
printer.processPage(page);
}
}
(ExtractImageLocations 测试 testExtractLikeHelloWorldImprovedFromTopSecret
)
因此,对于您的 PDF 文件,将找到图像:
Processing page: 1
*******************************************************************
Found image [R8]
position in PDF = 39.0, 102.48 in user space units
raw image size = 1209, 1640 in pixels
displayed size = 516.3119, 700.3752 in user space units
displayed size = 7.1709986, 9.727433 in inches at 72 dpi rendering
displayed size = 182.14336, 247.0768 in millimeters at 72 dpi rendering
小心,
这不是完美的修复,更多的是概念验证和解决方法,因为它既没有将图案正确限制到实际填充的区域,也没有 return 多次发现足够大的区域需要多个图案瓷砖来填充。尽管如此,它 return 是手头文件的图像匹配..