PDF Box getXObjectNames无法识别我的PDF上的条形码,但是可以识别出我上网的PDF文件上的条形码 一般 Sample PDF.pdf

问题描述

我正在尝试使用PdResources的getXObjectNames()从PDF中读取和读取条形码。

如果您看到上述JIRA项,则会看到随附的PDF文件。 当我在该PDF文件上运行代码时,会得到所需的输出(即打印条形码类型。)

但是,当我在PDF上运行它时,它无法识别其中的条形码。 (我检查过条形码实际上是图像而不是文本。)

听起来也很奇怪,但是它确实可以在我的PDF上运行一次,并且从那时起我还没有进行任何更改,但是现在肯定不起作用。 (由于某些原因,我无法共享PDF。)

有人遇到过类似的问题吗?

这也是我关于堆栈溢出的第一个问题。请告诉我我是否在任何地方错了。

这里是该pdf的链接https://drive.google.com/file/d/1PzVApIePg4U9XL399BpAd2oeY6Q2tLEB/view?usp=drivesdk

解决方法

一般

由于您没有显示代码,而只是将其描述为与PDFBOX-2124中的代码非常相似,并且正如您所说的,由于某些原因您无法共享PDF ,我只有要分析的代码。因此,我不能说出真正的问题是什么,只能列举一些可能的问题

首先,该代码仅检查给定页面的即时资源中是否有位图图像:

PDResources pdResources = pdPage.getResources();

Map<String,PDXObject> xobjects = (Map<String,PDXObject>) pdResources.getXObjects();
if (xobjects != null)
{
    for (String key : xobjects.keySet())
    {
        PDXObject xobject = xobjects.get(key);
        if (xobject instanceof PDImageXObject)
        {
            PDImageXObject imageObject = (PDImageXObject) xobject;
            String suffix = imageObject.getSuffix();
            if (suffix != null)
            {
                BufferedImage image = imageObject.getImage();
                extractBarcodeArrayByAreas(image,this.maximumBlankPixelDelimiterCount);
            }
        }
    }
}   

PDFBOX-2124 PdPageBarcodeScanner方法scsan

位图图像也可以存储在其他位置,例如

  • 在页面上使用的形式xobjects,pattern或Type 3字体的单独资源中;要找到它们,还必须检查其他页面资源,甚至是递归检查,因为图像可能是页面上使用的xobject形式中使用的模式的资源;
  • 在页面注释的单独资源中;因此,也必须递归到批注资源;
  • 内联到某些内容流中;因此,还必须搜索页面本身,页面资源(递归),页面注释及其资源(递归)的内容流。

此外,位图可能以PDFBox不知道如何导出为BufferedImage的某种格式(尤其是某些色彩空间)给出。

也可以使用应用于纯黑色位图的某些蒙版构造条形码,在这种情况下,您的代码可能仅尝试扫描纯黑色图像。

此外,您说

我检查过条形码实际上是图像而不是文本。

如果仅检查条形码是不是文本,则它可能不仅是位图图像,而且还可以通过矢量图形绘制说明。因此,您还必须检查所有内容流,以获取绘制条形码的矢量图形指令。

也可能有组合,例如绘制纯黑色内嵌位图图像等时,矢量图形的软蒙版可能会处于活动状态。

我确定我在这里错过了很多选择。


下一步,您可能需要分析无法共享的 PDF ,以了解条形码的绘制方式。

或者,将页面呈现为位图图像,然后使用zxing在大位图上搜索条形码。


Sample PDF.pdf

您提供了指向样本PDF的链接。因此,我尝试使用与PDFBOX-2124中的代码非常相似提取条形码。显然,那里有一些PDFBox 2.0.0-SNAPSHOT的代码,因此必须进行一些更正。特别是,您最终使用在问题标题中提到的方法getXObjectNames()

PDResources pdResources = pdPage.getResources();
int index = 0;

for (COSName name : pdResources.getXObjectNames()) {
    PDXObject xobject = pdResources.getXObject(name);
    if (xobject instanceof PDImageXObject)
    {
        PDImageXObject imageObject = (PDImageXObject) xobject;
        String suffix = imageObject.getSuffix();
        if (suffix != null)
        {
            BufferedImage image = imageObject.getImage();

            File file = new File(RESULT_FOLDER,String.format("Sample PDF-1-%s.%s",index,imageObject.getSuffix()));
            ImageIO.write(image,imageObject.getSuffix(),file);
            index++;
            System.out.println(file);
        }
    }
}

ExtractImages测试testExtractSamplePDFJayshreeAtak

输出:一个位图图像被导出为“ Sample PDF-1-0.tiff”,如下所示:

image as png

因此,我无法复制您的问题

PDF Box getXObjectNames()不能识别我的PDF上的条形码,但是可以识别我离开互联网的PDF文件上的条形码

很显然,getXObjectNames()确实返回了位图图像xobject资源的名称,而PDFBox恰好将其导出。

请使用您的代码检查是否未按照要求提取图像,或者稍后是否只能处理该图像。

如果您确实没有提取图像,

  • 更新您的PDFBox版本(我使用了当前的开发头,但是最新发布的版本应该返回相同的版本)
  • 更新您的Java,
  • 检查是否有多余的JAI jar可能引起麻烦。

如果在您的情况下,图像被提取但未按更高版本的代码预期进行分析,

  • 更彻底地调试以找出分析失败的地方,
  • 在此处针对QR码图像分析创建一个新问题,
  • 并提供足够的代码和tiff文件,以使人们可以实际重现该问题。