iText PDF;如何使用Java将jpeg2000转换为jpg
我正在尝试使用java、iText和java高级图像库解决一个问题。我的软件系统使用ghostscript创建jpg缩略图等。。。从PDF文件。然而,在CentOS 5.x上,ghostscript的最高版本是8.7,它存在一个已知的问题,即无法处理包含JPEG 2000图像的PDF文件。我的计划是先扫描文件,看看它是否包含jpeg2000图像(我已经弄清楚了这部分);如果是,则使用iText和Java高级图像库(包含jpeg2000读写编解码器)将包含的jpeg2000文件转换为常规jpeg文件,然后将新的PDF文件传递给ghostscript。下面的代码尝试执行此操作,但会生成另一个包含jpeg2000文件的文件。在此方面的任何帮助都将不胜感激iText PDF;如何使用Java将jpeg2000转换为jpg,java,itext,ghostscript,Java,Itext,Ghostscript,我正在尝试使用java、iText和java高级图像库解决一个问题。我的软件系统使用ghostscript创建jpg缩略图等。。。从PDF文件。然而,在CentOS 5.x上,ghostscript的最高版本是8.7,它存在一个已知的问题,即无法处理包含JPEG 2000图像的PDF文件。我的计划是先扫描文件,看看它是否包含jpeg2000图像(我已经弄清楚了这部分);如果是,则使用iText和Java高级图像库(包含jpeg2000读写编解码器)将包含的jpeg2000文件转换为常规jpeg文
public class ImageReplacer{
public static void main(String [] args){
try{
String RESULT = "";
PdfReader reader = new PdfReader("pdf_containing_jpeg2000_images.pdf");
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
MyImageRenderListener listener = new MyImageRenderListener(RESULT);
MyImageConverterListener clistener = new MyImageConverterListener(RESULT);
clistener.setReader(reader);
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
parser.processContent(i, clistener);
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("out.pdf"));
stamper.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
class MyImageConverterListener implements RenderListener {
protected String path = "";
protected PdfReader reader;
public MyImageConverterListener(String path) {
this.path = path;
}
public void beginTextBlock() { }
public void endTextBlock() { }
public void renderImage(ImageRenderInfo renderInfo) {
try {
PdfImageObject image = renderInfo.getImage();
PdfName filter = (PdfName)image.get(PdfName.FILTER);
if (PdfName.JPXDECODE.equals(filter)) {
if(image.getDictionary().isStream()){
BufferedImage bi = image.getBufferedImage();
if (bi == null) return;
int width = (int)bi.getWidth();
int height = (int)bi.getHeight();
ByteArrayOutputStream imgBytes = new ByteArrayOutputStream();
ImageIO.write(bi, "JPG", imgBytes);
PRStream stream = new PRStream(reader,imgBytes.toByteArray());
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);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void renderText(TextRenderInfo renderInfo) { }
public void setReader(PdfReader r){
reader = r;
}
}
公共类ImageReplacer{
公共静态void main(字符串[]args){
试一试{
字符串结果=”;
PdfReader reader=新的PdfReader(“pdf_包含_jpeg2000_images.pdf”);
PdfReaderContentParser=新的PdfReaderContentParser(读取器);
MyImageRenderListener=新的MyImageRenderListener(结果);
MyImageConverterListener clistener=新的MyImageConverterListener(结果);
设置读卡器(读卡器);
因为(inti=1;i所以我自己设法解决了这个问题(借助于Bruno Lowagie的《iText in action》一书中的一点帮助)。为了再次迭代,我打算使用iText扫描PDF,查看它是否包含任何JPEG2000图像,以及它是否输出相同的PDF,但内部JPEG2000图像替换为常规JPEG图像。这解决了致命的ghostscript 8.7“无法处理JPXDecode数据”错误,但也可用于制作PDF的iOS compa泰布尔
因此,没有更多的孩子,这是
步骤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();
}
}
}
import com.itextpdf.text.pdf.PdfReader;
导入com.itextpdf.text.pdf.PdfName;
导入com.itextpdf.text.pdf.PdfObject;
导入com.itextpdf.text.pdf.PRStream;
导入com.itextpdf.text.pdf.parser.PdfImageObject;
导入com.itextpdf.text.pdf.PdfNumber;
导入javax.imageio.imageio;
导入java.awt.image.buffereImage;
导入com.itextpdf.text.pdf.PdfStamper;
导入java.io.*;
公共类PDFConverter{
公共静态void main(字符串[]args){
如果(参数长度==1){
if(hasJpeg2000(args[0])){
System.out.println(“包含JPEG2000图像:将其转换为JPEG…”);
convertPDF(args[0]);
System.out.println(“完成…”);
}否则{
System.out.println(“不包含任何JPEG2000图像:无需执行任何操作…”);
}
}否则{
System.out.println(“请指定一个PDF文件名作为命令行参数!”);
}
}
公共静态布尔值hasJpeg2000(字符串s){
试一试{
PDF阅读器=新的PDF阅读器;
int n=reader.getXrefSize();
PdfObject对象;
溪流;
对于(int i=0;i
步骤3)按照以下方式编译上述文件:
javac-cp.:iText-5.0.4.jar:jai_imageio-1.1.jar PDFConverter.java
步骤4)使用PDF运行程序
java-cp.:iText-5。
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfObject;
import com.itextpdf.text.pdf.*;
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==2){
if(hasJpeg2000(args[0])){
System.out.println("Contains JPEG2000 images: Converting them to JPEG...");
convertPDF(args[0], args[1]);
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 and a output filename as a command line arguments!");
}
}
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;
PdfObject pdfsubtype = stream.get(PdfName.SUBTYPE);
System.out.println(pdfsubtype);
if (pdfsubtype != null && pdfsubtype.toString().equals(PdfName.IMAGE.toString())) {
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;
}
private static void filterObject(PdfImageObject image,PdfName filter,PRStream stream) throws java.io.IOException {
if (PdfName.JPXDECODE.equals(filter)) {
BufferedImage bi = image.getBufferedImage();
if (bi == null) return;
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);
}
}
public static void convertPDF(String s, String out){
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;
PdfObject pdfsubtype = stream.get(PdfName.SUBTYPE);
if (pdfsubtype != null && pdfsubtype.toString().equals(PdfName.IMAGE.toString())) {
PdfImageObject image = new PdfImageObject(stream);
Object listOrName = image.get(PdfName.FILTER);
if (listOrName instanceof PdfName) {
PdfName filter = (PdfName)image.get(PdfName.FILTER);
filterObject(image, filter, stream);
}
else if (listOrName instanceof PdfArray) {
PdfArray list = (PdfArray)image.get(PdfName.FILTER);
for (int j = 0; j < list.size(); j++) {
PdfName filter = list.getAsName(j);
filterObject(image, filter, stream);
}
}
else {
System.err.println("Unknown Obejcttype: " + listOrName);
}
}
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(out)); stamper.close();
} catch(Exception e){
e.printStackTrace();
}
}
}