当前位置: 首页 > 知识库问答 >
问题:

iText 7从jar文件读取背景图像

吕利
2023-03-14

我使用iText 7http://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。罐子,slf4j-simple-1.7.25。jar在项目中设置文档页面的背景图像,并在同一文档(pdf文件)中保存几个类似的页面。图像文件

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

必须作为资源存储在jar文件中。ImageData对象是使用com的方法create(java.awt.Image,java.awt.Color)创建的。itextpdf。伊奥。形象ImageDataFactory:

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

java的代码。awt。形象BuffereImage loadImage(String imageFilename)方法是:

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

问题是,在我从jar文件运行程序后,我得到了一个pdf文档,它比我使用直接图像引用从IDE运行程序时大得多(对于17页的文档,81 MB比9 MB):

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

如果使用com的create(byte[]bytes,boolean recoverImage)方法从图像的字节创建ImageData对象。itextpdf。伊奥。形象ImageDataFactory:

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

并使用byte[]loadImageByte(字符串imageFilename)方法:

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

无论是从IDE运行程序,还是从jar文件开始,生成的pdf文档的大小都很小。但是,在后一种情况下,文档不会打开,Adobe Acrobat 9会给出一个错误“图像数据不足”(两个文档的字节不同)。

文件大小不同的原因是什么?有没有一种方法可以通过从jar文件开始的程序来获取小尺寸的pdf文档?

共有1个答案

沈思博
2023-03-14

问题通过使用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文件的检查表明,当您使用add(Image Image)方法多次将相同的前景图像添加到文档对象中时,图像被添加为对单个PDF XObject的引用。同时,将背景图像类似的多次添加到具有addImage(ImageData Image, Rectangrect, boolean asInline)方法的PdfCanvas对象中,会创建几个不同的PDF XObject实例。注意这些方法的参数的差异。对iText 7库源代码的分析表明,Image类有一个PdfXObject成员,该成员在每次创建Image实例时都会创建,但是ImageData类与相应的PdfXObject没有关联。

 类似资料:
  • 我有一个困扰了我好几天的问题。。。我检查了类似的问题,但没有找到解决方案。 我使用NetBeans IDE。我建立项目jar文件,即“Clock.jar”,其中包含一个“时钟”命名文件夹,其中发现了一些图像、文本文件和所有项目类。下面的代码创建一个图像图标工作 但是下面读取文本文件的代码失败 正如您可能猜到的那样,引发了NullPointer异常,这意味着它可能找不到文件。 但是,为什么图像图标构

  • 问题内容: 我在JAR文件中有一个文件。这,例如。 我该如何访问?我的源代码是: 问题答案: 您不能使用File,因为此文件在文件系统上并不独立存在。相反,您需要getResourceAsStream(),如下所示:

  • 问题内容: 当我在eclipse中导出可执行jar文件时,也需要使用res文件夹进行编译,当我使用不起作用的方法时。 当前读取的图像代码 代码无效 问题答案: 我现在已经解决了问题-这是有效的代码 fileName的值只是一个图像名称,例如BufferedImage img = loadImage(“ background.png”); 感谢大家的帮助。

  • 你好,我最近把我的JavaFX8项目改为Maven,除了加载JAR旁边的文件外,一切都很好。这在以前起作用,但现在不起作用了。 文件夹结构: 要加载的图标位于/target/Icons中,JAR文件位于/target中 我读取文件的代码如下所示: 它进入循环并查找文件,但当新图像(file.getAbsoltePath())被调用时,它会崩溃。 我尝试了toExternalForm()等的各种方法

  • 我想从我的jar中读取一个资源,如下所示: 在Eclipse中运行它时工作良好,但如果我将它导出到一个jar中,然后运行它,就会出现一个IllegalArgumentException: 我真的不知道为什么,但通过一些测试我发现如果我改变 至 然后它的工作方式相反(它在jar中工作,但不能在eclipse中工作)。 我使用的是Eclipse,我的文件所在的文件夹位于类文件夹中。

  • 在我的maven项目中,我有一个PDF文件,它位于文件夹中。我的函数从文件夹读取PDF文件,并根据用户的数据在文档中添加一些值。 此项目使用打包为文件,并在我的其他Spring Boot应用程序中用作依赖项。 在我的Spring启动项目中,我创建了将在PDF上执行一些工作的类的instace。一旦PDF文件上的所有工作都完成,并且当PDF文件保存在文件系统上时,它始终是空的(所有页面都是空白的)。