0

对于一个学校项目,我正在为 PDF 开发图像提取器,为此我正在使用 PDFBox 库。我现在面临的问题是获取元数据,到目前为止,我只设法从 PDF 本身而不是从 PDF 中的图像获取元数据。

是否可以使用 PDFBox 从 PDF 中的所有图像中获取元数据?如果是这样,有人可以给我举个例子吗?到目前为止,我发现的所有示例都是针对 PDF 本身的元数据,而不是针对图像。

我还听说创建 PDF 时,它会从其中的对象中删除任何元数据,这是真的吗?

希望stackoverflow上的人可以帮助我。

4

1 回答 1

2

我不同意其他人的观点,并为您的问题提供了 POC:您可以通过以下方式使用pdfbox提取图像的 XMP 元数据:

public void getXMPInformation() {
    // Open PDF document
    PDDocument document = null;
    try {
        document = PDDocument.load(PATH_TO_YOUR_DOCUMENT);
    } catch (IOException e) {
        e.printStackTrace();
    }
    // Get all pages and loop through them
    List pages = document.getDocumentCatalog().getAllPages();
    Iterator iter = pages.iterator();
    while( iter.hasNext() ) {
        PDPage page = (PDPage)iter.next();
        PDResources resources = page.getResources();            
        Map images = null;
        // Get all Images on page
        try {
            images = resources.getImages();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if( images != null ) {
            // Check all images for metadata
            Iterator imageIter = images.keySet().iterator();
            while( imageIter.hasNext() ) {
                String key = (String)imageIter.next();
                PDXObjectImage image = (PDXObjectImage)images.get( key );
                PDMetadata metadata = image.getMetadata();
                System.out.println("Found a image: Analyzing for Metadata");
                if (metadata == null) {
                    System.out.println("No Metadata found for this image.");
                } else {
                    InputStream xmlInputStream = null;
                    try {
                        xmlInputStream = metadata.createInputStream();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        System.out.println("--------------------------------------------------------------------------------");
                        String mystring = convertStreamToString(xmlInputStream);
                        System.out.println(mystring);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                // Export the images
                String name = getUniqueFileName( key, image.getSuffix() );
                    System.out.println( "Writing image:" + name );
                    try {
                        image.write2file( name );
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        //e.printStackTrace();
                }
                System.out.println("--------------------------------------------------------------------------------");
            }
        }
    }
}

和“辅助方法”:

public String convertStreamToString(InputStream is) throws IOException {
    /*
     * To convert the InputStream to String we use the BufferedReader.readLine()
     * method. We iterate until the BufferedReader return null which means
     * there's no more data to read. Each line will appended to a StringBuilder
     * and returned as String.
     */
    if (is != null) {
        StringBuilder sb = new StringBuilder();
        String line;

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            while ((line = reader.readLine()) != null) {
                sb.append(line).append("\n");
            }
        } finally {
            is.close();
        }
        return sb.toString();
    } else {       
        return "";
    }
}

private String getUniqueFileName( String prefix, String suffix ) {
    /*
    * imagecounter is a global variable that counts from 0 to the number of
    * extracted images
    */
    String uniqueName = null;
    File f = null;
    while( f == null || f.exists() ) {
        uniqueName = prefix + "-" + imageCounter;
        f = new File( uniqueName + "." + suffix );
    }
    imageCounter++;
    return uniqueName;
}

注意:这是一个快速而肮脏的概念证明,而不是一个风格良好的代码。

在构建 PDF 文档之前,在 InDesign 中放置的图像必须具有 XMP 元数据。例如,可以使用 Photoshop 设置 XMP-Metdadata。请注意,并非所有 IPTC/Exif/... 信息都转换为 XMP 元数据。只有少数字段被转换。

我在 JPG 和 PNG 图像上使用此方法,这些图像放置在使用 InDesign 构建的 PDF 中。它运行良好,我可以在制作步骤后从准备好的 PDF(图片涂层)中获取所有图像信息。

于 2011-06-01T07:03:59.590 回答