我正在使用PDFBox从我的pdf中提取图像(仅包含jpg')。
由于我将这些图像保存在我的数据库中,我想先将每个图像直接转换为输入流对象,而不将文件暂时放在我的文件系统上。然而,我面临着这方面的困难。我认为必须这样做,因为我在以下示例中使用了image.getPDFStream().createInputStream()
:
while (imageIter.hasNext()) {
String key = (String) imageIter.next();
PDXObjectImage image = (PDXObjectImage) images.get(key);
FileOutputStream output = new FileOutputStream(new File(
"C:\\Users\\Anton\\Documents\\lol\\test.jpg"));
InputStream is = image.getPDStream().createInputStream(); //this gives me a corrupt file
byte[] buffer = new byte[1024];
while (is.read(buffer) > 0) {
output.write(buffer);
}
}
然而这有效:
while (iter.hasNext()) {
PDPage page = (PDPage) iter.next();
PDResources resources = page.getResources();
Map<String, PDXObject> images = resources.getXObjects();
if (images != null) {
Iterator<?> imageIter = images.keySet().iterator();
while (imageIter.hasNext()) {
String key = (String) imageIter.next();
PDXObjectImage image = (PDXObjectImage) images.get(key);
image.write2file(new File("C:\\Users\\Anton\\Documents\\lol\\test.jpg")); //this works however
}
}
}
知道如何将每个PDXObjectImage(或我能得到的任何其他对象)转换为输入流吗?
答案 0 :(得分:3)
在PDFBox 1.8中,最简单的方法是使用write2OutputStream(),所以你的第一个代码块现在看起来像这样:
while (imageIter.hasNext()) {
String key = (String) imageIter.next();
PDXObjectImage image = (PDXObjectImage) images.get(key);
FileOutputStream output = new FileOutputStream(new File(
"C:\\Users\\Anton\\Documents\\lol\\test.jpg"));
image.write2OutputStream(output);
}
高级解决方案,只要您确定只有正确显示的JPEG,即没有异常的色彩空间:
while (imageIter.hasNext()) {
String key = (String) imageIter.next();
PDXObjectImage image = (PDXObjectImage) images.get(key);
FileOutputStream output = new FileOutputStream(new File(
"C:\\Users\\Anton\\Documents\\lol\\test.jpg"));
InputStream is = image.getPDStream().getPartiallyFilteredStream(DCT_FILTERS);
byte[] buffer = new byte[1024];
while (is.read(buffer) > 0) {
output.write(buffer);
}
}
第二种解决方案会删除除DCT(= JPEG)滤镜之外的所有滤镜。一些较旧的PDF有几个过滤器,例如ascii85和DCT。
现在,即使您使用JPEG创建图像,也无法了解PDF创建软件的功能。找出它是什么类型的图像的一种方法是检查它是什么类(使用instanceof):
- PDPixelMap => PNG
- PDJpeg => JPEG
- PDCcitt => TIF
另一种方法是使用image.getSuffix()。
答案 1 :(得分:2)
PDXObjectImage
有方法write2OutputStream(OutputStream out)
,然后您可以从输出流中获取任一字节数组。
检查How to convert OutputStream to InputStream?以将OutputStream转换为InputStream。
答案 2 :(得分:0)
如果您使用的是PDFBox 2.0.0或更高版本
PDDocument document = PDDocument.load(new File("filePath")); //filePath is the path to your .pdf
PDFRenderer pdfRenderer = new PDFRenderer(document);
for(int i=0; i<document.getPages().getCount(); i++){
BufferedImage bim = pdfRenderer.renderImage(i, 1.0f, ImageType.RGB); //Get bufferedImage for page "i" with scale 1
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(bim, "jpg", os);
InputStream is = new ByteArrayInputStream(os.toByteArray());
//Do whatever you need with the inputstream
}
document.close()