当前位置: 首页 > 知识库问答 >
问题:

无法从PDFA1-a格式文档中提取图像

洪承天
2023-03-14

我使用以下代码从PDFA1格式的pdf中提取图像,但我无法获得图像。

List<PDPage> list = document.getDocumentCatalog().getAllPages();

String fileName = oldFile.getName().replace(".pdf", "_cover");
int totalImages = 1;
for (PDPage page : list) {

    PDResources pdResources = page.findResources();

    Map pageImages = pdResources.getImages();
    if (pageImages != null) {
        InputStream xmlInputStream = null;
        Iterator imageIter = pageImages.keySet().iterator();
        while (imageIter.hasNext()) {
            String key = (String) imageIter.next();
            PDXObjectImage pdxObjectImage = (PDXObjectImage) pageImages.get(key);

            System.out.println(convertStreamToString(xmlInputStream));
            System.out.println(pdxObjectImage.hashCode());
            System.out.println(pdxObjectImage.getColorSpace().getJavaColorSpace().isCS_sRGB());

            pdxObjectImage.write2file(destinationDir + fileName+ "_" + totalImages);
            totalImages++;

            break;
        }
    }
}

我能够使用上述代码提取非标准PDF的图像,但无法提取PDFA1-a格式PDF的图像。似乎是这样的

PDResources pdResources = page.findResources(); 

没有返回我甚至尝试过的图像页面。getResources(),但仍然无法获取任何图像。我甚至尝试过使用itext,但它仍然没有给我任何图像。

如果我尝试使用以下代码将PDF页面转换为图像

BufferedImage bufferedImage = page.convertToImage();
File outputfile = new File(destinationDir+"image1.JPEG");
ImageIO.write(bufferedImage, "JPEG", outputfile);

这些图像似乎没有与之关联的元数据,因此我仍然无法知道它们的dpi,或者它们是彩色还是灰度。

目前我正在使用PDFBox来做这件事。我已经花了2天的时间在谷歌上搜索,但我仍然没有找到任何代码或留档这样做。

如何在java中做到这一点??

是否可以在不提取图像的情况下获取DPI或pdf是彩色还是黑白??

共有1个答案

阎博易
2023-03-14

您的问题是两个问题的组合:

1) “中断;”。您的文件有两个图像。第一个是透明的,灰色的,或者其他的,JPEG编码的,但是它不是你想要的。第二个是您想要的,但在第一个映像之后中断。我刚把你的一段代码改成:

while (imageIter.hasNext())
{
     String key = (String) imageIter.next();
     PDXObjectImage pdxObjectImage = (PDXObjectImage) pageImages.get(key);
     System.out.println(totalImages);
     pdxObjectImage.write2file("C:\\SOMEPATH\\" + fileName + "_" + totalImages);
     totalImages++;

     //break;
 }

2) 您的第二个图像(有趣的一个)是JBIG2编码的。要解码这一点,您需要将levigo插件添加到您的类路径中,如本文所述。如果不这样做,您将在1.8.8中收到此消息,除非您禁用了日志记录:

ERROR [main] org.apache.pdfbox.filter.JBIG2Filter:69 - Can't find an ImageIO plugin to decode the JBIG2 encoded datastream.

(您没有收到该错误消息,因为它是第二条JBIG2编码的错误消息)

三个奖励提示:

3) 如果您自己创建了此图像,例如在复印机上,了解如何在不使用JBIG2压缩的情况下获取PDF图像,这有点冒险。

4) 不要使用PDR资源。getImages(),不推荐使用getImages调用。相反,请使用getXObjects(),然后检查html" target="_blank">迭代时得到的类型。

 Iterator imageIter = pageImages.keySet().iterator();
 while (imageIter.hasNext())
 {
     String key = (String) imageIter.next();
     Object o = pageImages.get(key);
     if (o instanceof PDXObjectImage)
     {
         PDXObjectImage pdxObjectImage = (PDXObjectImage) o;

         // do stuff
     }
 }

5)使用Foreach循环。

如果还不明显的话:这与PDF/A无关:-)

6)我忘了你还问过如何查看它是否是一个b/w图像,这里有一些我在评论中提到的简单代码(未优化):

BufferedImage bim = pdxObjectImage.getRGBImage();

boolean bwImage = true;

int w = bim.getWidth();
int h = bim.getHeight();
for (int y = 0; y < h; y++)
{
    for (int x = 0; x < w; x++)
    {
        Color c = new Color(bim.getRGB(x, y));
        int red = c.getRed();
        int green = c.getGreen();
        int blue = c.getBlue();
        if (red == 0 && green == 0 && blue == 0)
        {
            continue;
        }
        if (red == 255 && green == 255 && blue == 255)
        {
            continue;
        }
        bwImage = false;
        break;
    }
    if (!bwImage)
        break;
}
System.out.println(bwImage);
 类似资料:
  • 我知道以前也有人问过类似的问题,但是这些问题已经过时了(有些问题可以追溯到2006年)。 我有一个. net 3.5应用程序(w/iTextSharp 5),我正在转换为. net核心(iText 7),它从联邦快递跟踪文档中提取签名,通过SOAP服务以字节[]数组发送。这段代码多年来一直运行良好,只是略有更新。从联邦快递返回的PDF文档中有几个图像,但签名块不是110x46图像(这是pdf文件中

  • 我试图获取文档的URI时出错。"content://com.android.providers.downloads.documents/document/158“这是我得到的URI。我无法从这个URI获得路径。在这里,我共享了我的代码。

  • 我需要循环一些word文档,并从word文档中提取图像,并将其保存在单独的文件夹中。我尝试过将它们保存为超文本标记语言文档的方法,但它不太适合我的需求。 现在,我使用inlineshapes对象循环浏览图像,然后将它们复制粘贴到publisher文档上,然后将它们保存为图像。但是,在运行脚本时,我会遇到运行时自动化错误。对于使用Publisher运行时库,我尝试了早期绑定和晚期绑定,但都遇到了错误

  • 我在AWS上使用Kubernetes来运行一个Play+Akka流服务器。 执行时 我的吊舱进入“ImagePullBackoff”状态。 以下是事件列表: 但是,映像存在于存储库中--执行: 在我的机器上工作。 现在,这个节点上还有其他的豆荚在运行。

  • 问题内容: 如何 使用PHP 从PDF文档中提取文本? (我不能使用其他工具,我没有root用户访问权限) 我发现一些函数可用于纯文本,但是它们不能很好地处理Unicode字符: http://www.hashbangcode.com/blog/zend-lucene-and-pdf-documents-part-2-pdf- data-extraction-437.html 问题答案: 下载 c

  • 问题内容: 这是示例xml文档: 我想提取文本而不指定元素,我该怎么做,因为我有10个这样的文档。我想要这样做是因为我的问题是用户正在输入一个我不知道的单词,必须在其各自文本部分的所有10个xml文档中进行搜索。为此,我应该在不知道元素的情况下知道文本的位置。所有这些文档都不同的另一件事。 请帮忙!! 问题答案: 您可以简单地去除所有标签: 但是,如果您只想在Linux中搜索文件中的某些文本,则可