我试图编写一个程序来从PDF文件中提取所有嵌入的图像。不幸的是,许多输入文件导致类似的例外:
com.itextpdf.text.exceptions.UnsupportedPdfException: The color space [blah blah blah] is not supported.
生成回溯的文件受密码保护,我无法取消保护或共享密码,我很害怕。但是,我遇到了来自多个来源的多个文件的错误。这些文件在OS X Preview和Acrobat Reader中都是完全可见和可打印的,所以我很确定问题出在iText而不是文件上。
我在OS X 10.10.3上使用iText 5.5.6和Oracle JDK 1.8.0_31但是在几个iText,JDK和OS版本上发生了同样的错误;我刚刚开始询问它。
代码(主循环只用这个类的实例调用PdfReaderContentParser.processContent
):
package info.metalfatigue;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.PdfImageObject;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;
public class MyImageRenderListener implements RenderListener {
private final String path;
public MyImageRenderListener(final String path) {
this.path = path;
}
@Override
public void beginTextBlock() {
// NOP
}
@Override
public void renderText(
@SuppressWarnings("unused") final TextRenderInfo renderInfo) {
// NOP
}
@Override
public void endTextBlock() {
// NOP
}
@Override
public void renderImage(final ImageRenderInfo renderInfo) {
try {
final PdfImageObject image = renderInfo.getImage();
final PdfName filter = (PdfName)image.get(PdfName.FILTER);
if (PdfName.DCTDECODE.equals(filter)) {
@SuppressWarnings("boxing")
final String filename =
String.format(
path,
renderInfo.getRef().getNumber(),
"jpg");
final OutputStream os = new FileOutputStream(filename);
os.write(image.getImageAsBytes());
os.close();
} else if (PdfName.JPXDECODE.equals(filter)) {
@SuppressWarnings("boxing")
final String filename =
String.format(
path,
renderInfo.getRef().getNumber(),
"jp2");
final OutputStream os = new FileOutputStream(filename);
os.write(image.getImageAsBytes());
os.close();
} else {
final BufferedImage awtImage = image.getBufferedImage();
if (null != awtImage) {
@SuppressWarnings("boxing")
final String filename =
String.format(
path,
renderInfo.getRef().getNumber(),
"png");
final OutputStream os = new FileOutputStream(filename);
ImageIO.write(awtImage, "png", os);
os.close();
}
}
} catch (final IOException e) {
e.printStackTrace();
}
}
}
示例异常追溯:
com.itextpdf.text.exceptions.UnsupportedPdfException: The color space [/DeviceN, [/Black], /DeviceCMYK, 1153 0 R, 1152 0 R] is not supported.
at com.itextpdf.text.pdf.parser.PdfImageObject.decodeImageBytes(PdfImageObject.java:323)
at com.itextpdf.text.pdf.parser.PdfImageObject.<init>(PdfImageObject.java:200)
at com.itextpdf.text.pdf.parser.PdfImageObject.<init>(PdfImageObject.java:169)
at com.itextpdf.text.pdf.parser.ImageRenderInfo.prepareImageObject(ImageRenderInfo.java:124)
at com.itextpdf.text.pdf.parser.ImageRenderInfo.getImage(ImageRenderInfo.java:114)
at info.metalfatigue.MyImageRenderListener.renderImage(MyImageRenderListener.java:42)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor$ImageXObjectDoHandler.handleXObject(PdfContentStreamProcessor.java:1268)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor.displayXObject(PdfContentStreamProcessor.java:352)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor.access$6100(PdfContentStreamProcessor.java:60)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor$Do.invoke(PdfContentStreamProcessor.java:988)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor.invokeOperator(PdfContentStreamProcessor.java:286)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor.processContent(PdfContentStreamProcessor.java:429)
at com.itextpdf.text.pdf.parser.PdfReaderContentParser.processContent(PdfReaderContentParser.java:80)
at info.metalfatigue.PdfImgEx.main(PdfImgEx.java:23)