【问题标题】:Is there any field to hold an image in PDFBOX-1.8.10?PDFBOX-1.8.10 中是否有任何字段可以保存图像?
【发布时间】:2015-12-06 13:52:46
【问题描述】:

在 PDFBOX 中,我想插入一些图像作为可以存储在 acroform 中的表单域。 稍后对于用户在特定 PDTextBox 字段中的一些值更改,我想调用 Javascript 函数来显示/隐藏上面的图像字段。还要确认 javascript 中是否支持隐藏/显示图像字段(即,如果我能够为此类图像字段命名,那么我认为这是可能的)。

PDFBOX 1.8.10 中是否有实现此目标的功能? 如果是,请提供参考代码/文档。

感谢您的帮助。

【问题讨论】:

  • 我怀疑示例中是否存在类似的内容。我认为最好的办法是使用 Adob​​e Acrobat(可能是试用版)创建这样的文件,然后使用 PDFBox 中可用的方法通过使用 PDFDebugger 查看文件(最好是 2.0 版本,这很更好的)。恐怕不容易。
  • @TilmanHausherr,我已经检查了 Adob​​e Acrobat 以创建这样的图像字段,但没有这样的选项。我们不能有任何称为图像字段的控件类型,图像直接添加到 PDF 中,但不能作为 acroform 的一部分包含。
  • @TilmanHausherr,我发现 PDSignatureField 是一种可以以字段形式嵌入图像的字段。是否可以在 PDSignatureField 类的帮助下创建这样的自定义 PDField 类,即通过查看其源代码并创建扩展 PDField 的自定义图像字段类。这是可行的选择吗?我怀疑创建这样的自定义字段会对我们有所帮助,因为在 PDFBox 中只有四种字段类型 - 文本、复选框、按钮和签名。对于其他类型,PDFBox 可能未设置 COSDictionary 对象或可能引发异常。如果您有任何想法,请告诉我。
  • 理论上,普通字段应该是可以的,因为“外观流”(即“你所看到的”)是“Form XObjects”,它们有一个内容流和资源,就像一个PDF 页面。但我从来没有测试过这个。问题是这将是几个小时,也许是几天的工作(和痛苦)来创造这一切,所以我没有帮助:-(你的第二句话:我的想法是关于普通领域。视觉签名是一个更加复杂的混乱:-(
  • 让事情变得更加混乱:术语“Form XObjects”与 Acroform 无关。这些只是内容流(= PDF 运算符及其参数的序列),其资源可以从页面内容流中调用,或用作外观流。

标签: javascript java pdf-generation pdfbox


【解决方案1】:

我已解决上述问题,将图像视为字段。

我已经获取了 PDPushButton 字段并在其中设置了图像,这样我也可以通过 java 脚本显示/隐藏图像。

看下面的示例代码:

package sample.pdfbox.example;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.imageio.ImageIO;

import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSFloat;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSString;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDPixelMap;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDPushButton;

public class MyPushButton2 
{
    public static void main(String arg[])  throws IOException, COSVisitorException
    {
        PDDocument document = new PDDocument();
        PDPage page = new PDPage(PDPage.PAGE_SIZE_LETTER);
        document.addPage(page);

        PDFont font = PDType1Font.HELVETICA;
        PDResources res = new PDResources();
        String fontName = res.addFont(font);
        String da = "/Helv 0 Tf 0 g";

        COSDictionary acroFormDict = new COSDictionary(); 
        acroFormDict.setItem(COSName.FIELDS, new COSArray());
        acroFormDict.setItem(COSName.DA, new COSString(da));

        PDAcroForm acroForm =  new PDAcroForm(document, acroFormDict);
        acroForm.setDefaultResources(res);
        document.getDocumentCatalog().setAcroForm(acroForm);


        float x = 10f;
        float y = page.getMediaBox().getHeight();  
        float yOffset = 15f;
        float yCurrent = y - yOffset;  

     // Create appearance stream for local image
        COSArray rectStream = new COSArray();
        rectStream.add(new COSFloat(0));
        rectStream.add(new COSFloat(0));
        rectStream.add(new COSFloat(25));
        rectStream.add(new COSFloat(25));

        final PDRectangle boundingBox = new PDRectangle(rectStream);
        InputStream imageStream = MyPushButton2.class.getResourceAsStream("/Penguins.jpg");
        BufferedImage bImage = ImageIO.read(imageStream);
        PDXObjectImage image = new PDPixelMap(document,bImage);

        PDResources holderFormResources = new PDResources();
        PDStream holderFormStream = new PDStream(document);
        PDXObjectForm holderForm = new PDXObjectForm(holderFormStream);
        holderForm.setResources(holderFormResources);
        holderForm.setBBox(boundingBox);
        holderForm.setFormType(1);

        PDAppearanceDictionary appearance = new PDAppearanceDictionary();
        appearance.getCOSObject().setDirect(true);
        PDAppearanceStream appearanceStream = new PDAppearanceStream(holderForm.getCOSStream());
        appearance.setNormalAppearance(appearanceStream);

        PDResources innerFormResources = new PDResources();
        PDStream innerFormStream = new PDStream(document);
        PDXObjectForm innerForm = new PDXObjectForm(innerFormStream);
        innerForm.setResources(innerFormResources);
        innerForm.setBBox(boundingBox);
        innerForm.setFormType(1);

        String innerFormName = holderFormResources.addXObject(innerForm, "FRM");

        PDResources imageFormResources = new PDResources();
        PDStream imageFormStream = new PDStream(document);

        PDXObjectForm imageForm = new PDXObjectForm(imageFormStream);
        imageForm.setResources(imageFormResources);
        imageForm.setBBox(boundingBox);
        imageForm.setFormType(1);

        String imageFormName = innerFormResources.addXObject(imageForm, "n");
        String imageName = imageFormResources.addXObject(image, "img");

        String holderFormComment = "q 1 0 0 1 0 0 cm /" + innerFormName + " Do Q \n";
        String innerFormComment = "q q 5 0 0 5 0 0 cm /" + imageFormName + " Do Q\n";
        String imgFormComment = "q 5 0 0 5 0 0 cm /" + imageName + " Do Q\n";

        appendRawCommands(holderFormStream.createOutputStream(), holderFormComment);
        appendRawCommands(innerFormStream.createOutputStream(), innerFormComment);
        appendRawCommands(imageFormStream.createOutputStream(), imgFormComment);

        // Create Pushbutton containing status image
        COSDictionary cosDict = new COSDictionary();
        COSArray rect = new COSArray();
        rect.add(new COSFloat(100));
        rect.add(new COSFloat(500));
        rect.add(new COSFloat(300));
        rect.add(new COSFloat(700));

        cosDict.setItem(COSName.RECT, rect);
        cosDict.setItem(COSName.FT, COSName.getPDFName("Btn")); // Field Type
        cosDict.setItem(COSName.TYPE, COSName.ANNOT);
        cosDict.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));
        cosDict.setItem(COSName.T, new COSString("ImageField1"));
        cosDict.setInt(COSName.F, 4);
        cosDict.setInt(COSName.FF, 65536);

        PDPushButton button = new PDPushButton(document.getDocumentCatalog().getAcroForm(), cosDict);
        button.setReadonly(true);

        button.getWidget().setAppearance(appearance);
        page.getAnnotations().add(button.getWidget());                          
        acroForm.getFields().add(button); // Added this line for Tilman's comment

        yCurrent = yCurrent - 20 - yOffset;

        File file = new File("C:\\pdf\\ImageButton.pdf");
        System.out.println("Sample file saved at : " + file.getAbsolutePath());
        document.save(file);
        document.close();
    }

    public static void appendRawCommands(OutputStream os, String commands) throws IOException {
        os.write(commands.getBytes("ISO-8859-1"));
        os.close();
    }

}

希望这个解决方案有帮助!!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 2018-03-25
    相关资源
    最近更新 更多