Java 如何检测PDF页面中是否有图像

Java 如何检测PDF页面中是否有图像,java,pdf,itext,Java,Pdf,Itext,我正在处理PDF/A样式的PDF文档,这些文档混合了扫描入的全页大小的图像,然后在图像页面之后的一两页中包含ColumnText对象中的文本 使用Java,如何检测哪些页面具有图像 检测哪些页面包含图像或文本的目的是确定第一个包含文本的页面出现的位置。我需要编辑文本或用更新的文本替换页面。带有图像的页面将保持不变 我正在使用iText5,目前没有升级到iText7的选项 以下是我用@mkl提供的解决方案实现的解决方案: ImageDetector.java package org.test.pd

我正在处理PDF/A样式的PDF文档,这些文档混合了扫描入的全页大小的图像,然后在图像页面之后的一两页中包含ColumnText对象中的文本

使用Java,如何检测哪些页面具有图像

检测哪些页面包含图像或文本的目的是确定第一个包含文本的页面出现的位置。我需要编辑文本或用更新的文本替换页面。带有图像的页面将保持不变

我正在使用iText5,目前没有升级到iText7的选项

以下是我用@mkl提供的解决方案实现的解决方案:

ImageDetector.java

package org.test.pdf;

import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;

public class ImageDetector implements RenderListener {
    public void beginTextBlock() { }
    public void endTextBlock() { }
    public void renderText(TextRenderInfo renderInfo) {
        textFound = true;
    }

    public void renderImage(ImageRenderInfo renderInfo) {
        imageFound = true;
    }

    boolean textFound = false;
    boolean imageFound = false;
}
PdfDocumentServiceTest.java

package org.test.pdf;

import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import com.test.PdfService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

@ActiveProfiles({"local", "testing"})
@DirtiesContext
@Transactional
@RunWith(SpringRunner.class)
@SpringBootTest
public class PdfDocumentServiceTest {

    @Autowired
    private PdfService pdfService;

    @Test
    public void testFindImagesInPdf(Long pdfId)) {
        final byte[] resource = PdfService.getPdf(pdfId);
        int imagePageCount = 0;
        int textPageCount = 0;
        if (resource != null && resource.length > 0) {
            PdfReader reader = new PdfReader(resource);
            PdfReaderContentParser parser = new PdfReaderContentParser(reader);

            for (int pageNumber = 1; pageNumber <= reader.getNumberOfPages(); pageNumber++) {

                ImageDetector imageDetector = new ImageDetector();
                parser.processContent(pageNumber, imageDetector);

                if (imageDetector.imageFound) {
                    imagePageCount++;
                }
                if (imageDetector.textFound) {
                    textPageCount++;
                }
            }
            Assert.assertTrue(imagePageCount > 0);
            Assert.assertTrue(textPageCount > 0);
        }
    }
}
package org.test.pdf;
导入com.itextpdf.text.pdf.PdfReader;
导入com.itextpdf.text.pdf.parser.PdfReaderContentParser;
导入com.test.PdfService;
导入org.junit.Assert;
导入org.junit.Test;
导入org.junit.runner.RunWith;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.boot.test.context.SpringBootTest;
导入org.springframework.test.annotation.DirtiesContext;
导入org.springframework.test.context.ActiveProfiles;
导入org.springframework.test.context.junit4.SpringRunner;
导入org.springframework.transaction.annotation.Transactional;
@ActiveProfiles({“本地”,“测试”})
@肮脏的环境
@交易的
@RunWith(SpringRunner.class)
@春靴测试
公共类PdfDocumentServiceTest{
@自动连线
私人PDF服务PDF服务;
@试验
公共无效testFindImagesInPdf(长pdfId)){
最终字节[]resource=PdfService.getPdf(pdfId);
int imagePageCount=0;
int textPageCount=0;
if(resource!=null&&resource.length>0){
PdfReader reader=新PdfReader(资源);
PdfReaderContentParser=新的PdfReaderContentParser(读取器);
对于(int pageNumber=1;pageNumber 0);
Assert.assertTrue(textPageCount>0);
}
}
}

尝试下面的代码示例(需要库),希望它对您有用

    PdfDocument doc = new PdfDocument();
    doc.loadFromFile("sample.pdf");

    for(int i = 0; i < doc.getPages().getCount(); i ++) {
        PdfPageBase page = doc.getPages().get(i);
        PdfImageInfo[] imageInfo = page.getImagesInfo();

        if (imageInfo != null && imageInfo.length > 0) {
            System.out.println("Page" + i + "contains image");
        } 
        else {
            System.out.print("Page" + i + "doesn't contain image");
        }
PdfDocument doc=新的PdfDocument();
doc.loadFromFile(“sample.pdf”);
对于(int i=0;i0){
System.out.println(“页面“+i+”包含图像”);
} 
否则{
系统输出打印(“页面“+i+”不包含图像”);
}

免责声明:我为Spire工作。

使用iText 5,您可以通过将页面内容解析为自定义的
RenderListener
实现来确定图像是否实际显示在页面上

类ImageDetector实现RenderListener{
public void beginTextBlock(){}
public void endTextBlock(){}
public void renderText(TextRenderInfo renderInfo){}
公共无效渲染图像(ImageRenderInfo renderInfo){
imageFound=true;
}
布尔值imageFound=false;
}
这样使用:

PdfReader reader=新的PdfReader(资源);
PdfReaderContentParser=新的PdfReaderContentParser(读取器);

对于(int pageNumber=1;pageNumber First),您应该使用某种库(例如apachepdfbox)解析和分析PDF文档,因为PDF是一种相当复杂的文档格式。查找包含图像的页面的最简单方法是遍历页面树,查看页面的资源字典是否包含图像对象。但是,这并不是万无一失的:页面也可以通过嵌套对象间接引用图像。因此,您还必须递归地查看页面的XObject、Shading和Patterns。要确定,您必须检查这些对象是否在内容流中被引用——仅仅因为文档包含图像,并不意味着如果您在PDF阅读器中打开文档,它实际上是可见的。@AndreasMayer,我将添加一个示例到目前为止我所做的工作。我正在使用PdfReader。
PdfReader
听起来像是类名,而不是库名。我知道至少有两个不同的pdf库具有相同的类名。请澄清。@mkl,我正在使用iText5(com.itextpdf.text.pdf.PdfReader)。
page.getImagesInfo()
是否表示页面资源中的图像(已使用和未使用)或页面上实际使用的图像(内联,来自页面资源,或来自页面上显示的xobject资源)?作为旁白,
doc.getPages().indexOf(page)
只是编写
i
的一种复杂方式,不是吗?@mkl page.getImagesInfo()表示页面中的所有图像。抱歉,我犯了一个愚蠢的错误:(,刚刚更新了答案,感谢您指出。“页面中的所有图像”-在页面中作为PDF对象(即在页面资源中),在页面中作为显示单元(即用于呈现页面的所有图像),或两者的组合?效果很好!!我将把我的代码添加到原始问题中。