Так что мне удалось решить это самостоятельно (с небольшой помощью iText в действии Бруно Лоуаги - отличная книга). Просто для повторения, я собираюсь отсканировать PDF, используя iText, чтобы увидеть, содержит ли он какие-либо изображения JPEG2000 и выводит ли он тот же PDF, но с внутренними изображениями JPEG2000, замененными обычными изображениями JPEG. Это решает фатальную ошибку ghostscript 8.7 «Невозможно обработать данные JPXDecode», но также может пригодиться для обеспечения совместимости PDF с iOS.
Так что, без дальнейших усилий, дети; здесь идет ...
Шаг 1) Загрузите файл iText 5.x .jar и загрузите jai_imageio-1.1.jar (расширенная библиотека изображений Java, которая позволяет конвертировать файлы JPEG2000)
Шаг 2) Создайте файл с именем PDFConverter.java и поместите в него этот код:
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfObject;
import com.itextpdf.text.pdf.PRStream;
import com.itextpdf.text.pdf.parser.PdfImageObject;
import com.itextpdf.text.pdf.PdfNumber;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import com.itextpdf.text.pdf.PdfStamper;
import java.io.*;
public class PDFConverter{
public static void main(String [] args){
if(args.length==1){
if(hasJpeg2000(args[0])){
System.out.println("Contains JPEG2000 images: Converting them to JPEG...");
convertPDF(args[0]);
System.out.println("Done...");
}else{
System.out.println("Doesn't contain any JPEG2000 images: Nothing to be done...");
}
}else{
System.out.println("Please specify a PDF filename as a command line argument!");
}
}
public static boolean hasJpeg2000(String s){
try{
PdfReader reader = new PdfReader(s);
int n = reader.getXrefSize();
PdfObject object;
PRStream stream;
for (int i = 0; i < n; i++) {
object = reader.getPdfObject(i);
if (object == null || !object.isStream())continue;
stream = (PRStream)object;
PdfImageObject image = new PdfImageObject(stream);
PdfName filter = (PdfName)image.get(PdfName.FILTER);
if (PdfName.JPXDECODE.equals(filter)) {
return true;
}
}
}catch(Exception e){
e.printStackTrace();
}
return false;
}
public static void convertPDF(String s){
try{
PdfReader reader = new PdfReader(s);
int n = reader.getXrefSize();
PdfObject object;
PRStream stream;
for (int i = 0; i < n; i++) {
object = reader.getPdfObject(i);
if (object == null || !object.isStream())continue;
stream = (PRStream)object;
PdfImageObject image = new PdfImageObject(stream);
PdfName filter = (PdfName)image.get(PdfName.FILTER);
if (PdfName.JPXDECODE.equals(filter)) {
BufferedImage bi = image.getBufferedImage();
if (bi == null) continue;
int width = (int)(bi.getWidth());
int height = (int)(bi.getHeight());
ByteArrayOutputStream imgBytes = new ByteArrayOutputStream();
ImageIO.write(bi, "JPG", imgBytes);
stream.clear();
stream.setData(imgBytes.toByteArray(),false, PRStream.NO_COMPRESSION);
stream.put(PdfName.TYPE, PdfName.XOBJECT);
stream.put(PdfName.SUBTYPE, PdfName.IMAGE);
stream.put(new PdfName("foo"+Math.random()), new PdfName("bar"+Math.random()));
stream.put(PdfName.FILTER, PdfName.DCTDECODE);
stream.put(PdfName.WIDTH, new PdfNumber(width));
stream.put(PdfName.HEIGHT, new PdfNumber(height));
stream.put(PdfName.BITSPERCOMPONENT,new PdfNumber(8));
stream.put(PdfName.COLORSPACE, PdfName.DEVICERGB);
}
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("out.pdf")); stamper.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
Шаг 3) Скомпилируйте вышеуказанный файл следующим образом:
javac -cp.: IText-5.0.4.jar: jai_imageio-1.1.jar PDFConverter.java
Шаг 4) Запустить программу с PDF ...
java -cp.: IText-5.0.4.jar: jai_imageio-1.1.jar PDFConverter PDFFileName.pdf
Буйя ...