对于一个学校项目我正在使用PDF的图像提取器,因为我正在使用PDFBox库。 我现在面临的问题是获取元数据,到目前为止,我只是设法从PDF本身获取元数据,而不是从PDF中的图像中获取元数据。
是否可以使用PDFBox从PDF中的所有图像中获取元数据?如果是这样,有人可以举个例子吗? 到目前为止我发现的任何例子都是PDF本身的元数据,而不是图像。
我也听说过创建PDF时,它会删除对象中的所有元数据,这是真的吗?
希望stackoverflow上有人可以帮助我。
答案 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(图片涂层)的生产步骤之后获得所有图像信息。