2017-07-02 53 views
0

我使用iText 7 http://itextpdf.com/庫:itext7-io-7.0.2.jar,itext7-kernel-7.0.2.jar,itext7-layout-7.0.2.jar,slf4j- api-1.7.25.jar,slf4j-simple-1.7.25.jar在 設置文檔頁面的背景圖像並在同一文檔(pdf文件)中保存多個類似頁面的項目中。圖像文件iText 7從jar文件中讀取背景圖像

final String IMAGE = "/resources/image.jpg"; 

必須作爲資源存儲在jar文件中。

ImageData imgData = ImageDataFactory.create(new Main().loadImage(IMAGE), true); 

的java.awt中的代碼:所述的ImageData對象正在使用的方法創建的com.itextpdf.io.image.ImageDataFactory(java.awt.Image中圖像,java.awt.Color中的顏色)創建。 image.BufferedImage的LoadImage(字符串映像文件名稱)的方法是:

private BufferedImage loadImage(String imageFilename) { 
    BufferedImage img = null; 
    try { 
     img = javax.imageio.ImageIO.read(getClass().getResourceAsStream(imageFilename)); 
    } catch (IOException ex) { 
     Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    return img; 
} 

的的ImageData對象用於在循環:

Document document = ... (get Document object) 
PdfDocument pdf = document.getPdfDocument(); 
PageSize pageSize = pdf.getDefaultPageSize(); 
PdfPage page = pdf.addNewPage(); 
for (int i = 0; i < documents.size(); i++) { 
     PdfCanvas canvas = new PdfCanvas(page); 
     canvas.addImage(imgData, pageSize, false); 
     ... (add document body) 
     if (i < documents.size() - 1) { 
      page = pdf.addNewPage(); 
      document.add(new AreaBreak(AreaBreakType.NEXT_PAGE)); 
     } 
} 
document.close(); 

的問題是,我從罐子文件運行該程序後,我得到一個pdf文件,是mu CH當我使用直接圖像基準(81兆字節比9兆字節17頁文件)從IDE運行程序大於:

ImageData imgData = ImageDataFactory.create("src/resources/image.jpg"); 

如果使用該方法創建的圖像的字節創建的ImageData對象(字節[]字節,布爾recoverImage)com.itextpdf.io.image.ImageDataFactory的:

ImageData imgData = ImageDataFactory.create(new Main().loadImageByte(IMAGE), true); 

和使用字節[] loadImageByte(字符串映像文件名稱)方法:

private byte[] loadImageByte(String imageFilename) { 
    byte[] dataBytes = null; 
    try { 
     InputStream is = getClass().getResourceAsStream(imageFilename); 
     dataBytes = new byte[is.available()]; 
     is.read(dataBytes); 
    } catch (IOException ex) { 
     Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    return dataBytes; 
} 

在Si當您從IDE運行程序或從jar文件啓動時,生成的pdf文檔的大小很小。 但是,在後一種情況下,文檔無法打開,Adobe Acrobat 9發出「圖像數據不足」錯誤(兩個文檔的字節不同)。

什麼是文件大小之間的差異的原因是什麼,有沒有辦法從一個jar文件從程序開始得到一個小尺寸的pdf文檔?

+0

0123我需要詳細檢查一切,但是關於不同文件大小的一個可能的解釋是,在較小尺寸的情況下,圖像作爲XOBject存儲一次並在整個文檔中引用並在在較大的文件的情況下,圖像每次都被添加到整個文件中。 –

+0

關於通過'loadImageByte'進行第二次嘗試:使用'is.available()'來確定資源文件的大小。然而,這是錯誤的,'is.available()'可能會返回一個較小的值,具體取決於實際使用的'InputStream'類,實際使用的'InputStream'類可能會因IDE資源位於文件系統並從JAR壓縮文件中壓縮的資源運行。 – mkl

+0

這是指出,你可以分享用於重現問題的圖像文件? – mkl

回答

0

的問題通過使用PdfImageXObject包裝圖像數據解決:

public static final String IMAGE = "/resources/image.jpg"; 
public static final String DEST = "result.pdf"; 

public static void main(String[] args) throws FileNotFoundException { 

    int pageNumber = 5; 
    PdfWriter writer = new PdfWriter(DEST); 
    PdfDocument pdf = new PdfDocument(writer); 
    Document document = new Document(pdf, PageSize.A4.rotate()); 
    ImageData imgData = ImageDataFactory.create(new Main().loadImageByte(IMAGE), true); 
    /*Wrapping image data in a PdfImageXObject*/ 
    PdfImageXObject imgObject = new PdfImageXObject(imgData); 
    /*Calculate the page area for the image - the image size will change*/ 
    PageSize pageSize = pdf.getDefaultPageSize(); 
    Rectangle rectangle = new Rectangle(pageSize.getWidth(), pageSize.getHeight()); 
    /*Loop*/ 
    PdfPage page = pdf.addNewPage(); 
    for (int i = 0; i < pageNumber; i++) { 
     PdfCanvas canvas = new PdfCanvas(page); 
     /*Add background image as PdfImageXObject*/ 
     canvas.addXObject(imgObject, rectangle); 

     (PDF building blocks adding) 

     if (i < pageNumber - 1) { 
      page = pdf.addNewPage(); 
      document.add(new AreaBreak(AreaBreakType.NEXT_PAGE)); 
     } 
    } 
    document.close(); 
} 

PDFXplorer生成的PDF文件的檢查表明,當你同樣的前景圖像多次與添加到Document對象add(Image image)方法,圖像被添加爲單個PDF XObject的引用。同時,使用addImage(ImageData image, Rectangle rect, boolean asInline)方法將PdfCanvas對象與PdfCanvas類似的背景圖像相似地多次添加將創建多個不同的PDF XObject實例。 注意這些方法的參數差異。對iText 7庫源代碼的分析表明,Image類具有每創建一個Image實例時創建的PdfXObject成員,但ImageData類不與相應的PdfXObject關聯。