PDFBox图像元数据

时间:2011-04-01 18:53:38

标签: java pdf pdfbox

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

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

我也听说过创建PDF时,它会删除对象中的所有元数据,这是真的吗?

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

1 个答案:

答案 0 :(得分: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。请注意,那个p.e.并非所有IPTC / Exif / ...信息都转换为XMP元数据。只转换了少量字段。

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