2011-12-19 43 views
0

私は、Java、iText、およびJavaの高度なイメージングライブラリを使用して問題を解決しようとしています。私のソフトウェアシステムは、ghostscriptを使用してPDFファイルからjpgサムネイル画像などを作成します。しかし、CentOS 5.xではゴーストスクリプトの最高バージョンが8.7で、JPEG 2000画像を含むPDFファイルを扱うことができないという既知の問題があります。私の計画は、最初にファイルをスキャンして、jpeg2000イメージが含まれているかどうかを確認することです(私はすでにこの部分を把握しています)。そうであれば、iTextとJava Advanced Imagingライブラリ(jpeg2000 read &書き込みコーデックを含む)を使用して、含まれているjpeg2000ファイルを正規のjpegファイル&に変換し、新しいPDFファイルをghostscriptに渡します。以下のコードはこれを試みますが、jpeg2000ファイルを含む別のファイルになります。これについてのどんな助けも大いに感謝されるでしょう。iText PDF; Javaを使用してjpeg2000をJPGに変換する方法

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; 
    } 
} 

答えて

1

だから私は(ブルーノLowagieによるアクションでiTextのから少し助けを借りて - 素晴らしい本)自分でこれを解決するために管理。 iTextを使ってPDFをスキャンして、JPEG2000画像が含まれているかどうか、同じPDFを出力するかどうか、内部のJPEG2000画像を通常のJPEG画像に置き換えて調べることです。これは、致命的なゴーストスクリプト8.7「JPXDecodeデータを処理できませんでした」エラーを解決しますが、PDFのiOSとの互換性を持たせるのにも役立ちます。

これ以上子どもがいなくても、ここでは...

ステップ1)iTextの5.xの.jarファイルをダウンロードし、あなたはJPEG2000ファイルを変換することができます(Javaの高度な画像処理ライブラリjai_imageio-1.1.jarをダウンロードするには)行く

ステップ2)を作成しますPDFConverter.javaと呼ばれ、その中にこのコードを入れたファイル:

のjavac -cp::。iTextの-5.0.4.jar:jai_imageio

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)次のように上記のファイルをコンパイルします。 -1.1.jar PDFConverter.java

ステップ4)PDF ...

のjava -cpでプログラムを実行します。iTextの-5.0.4.jar:jai_imageio-1.1.jar PDFConverter PDFFileName.pdf

Booyah ...

1

素晴らしいですが、GlassFish v3.1にいくつか問題がありました。 GlassfishはClasspathにjai_imageio-1.1.jarがないかのように動作しました。私は "/ path/to/glassfish/domains/domain1/lib/ext /"フォルダにこのjai_imageio.jarを置くことを修正しました。

1

私のPDFにGhostScript on CentOS 5.3 - Unable to process JPXDecode dataの埋め込み要素の種類が異なるため、ReeceのPDFConverterにいくつかのNullPointerの問題がありました。だから、いくつかのObject/Typeチェックを行い、出力ファイル名をコマンドラインに追加しました。

他のすべては素晴らしい画像jpeg2000の問題に最適です。 Reeceのおかげで:)

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(); 
     } 
    } 

} 
関連する問題