提问者:小点点

使用itext库在pdf文档中添加内联图像


我们创建了一个使用itext5库生成pdf文档的应用程序。作为pdf生成的一部分,我们尝试在pdf中嵌入一个不可编辑且只读的内联图像。我们尝试了PdfContentByte的addImage方法,如下所示,

byte[] decoded = Base64.getDecoder().decode(encodedImage);
image = Image.getInstance(decoded);

检索到此图像后,在addImage方法中使用相同的方法。

PdfContentByte canvas =  pdfStamper.getOverContent(item.getPage(0));
canvas.addImage(image, Boolean.TRUE);

结果:由于图像是Base 64字符串格式,因此图像不会显示在生成的pdf文档中(如果图像不是Base 64格式,它可以正常工作)。

当我们打开pdf时,显示以下错误 :-------

我们如何处理这种情况?。

是否有其他方法来实现此要求。请帮助

代码:-

PdfReader resultantPdfReader = new PdfReader("template.pdf");

PdfStamper resultandPdfStamper = new PdfStamper(resultantPdfReader, new FileOutputStream("A13.pdf"));

AcroFields acroFields = resultantPdfReader.getAcroFields();
Rectangle fieldPosRec = acroFields.getFieldPositions("imageField").get(0).position;

String encodedSignature = ""; 
encodedSignature = new String(Files.readAllBytes(Paths.get("MyImage.png")));

if(encodedSignature.indexOf("data:image/png;base64,") != -1) {
    encodedSignature = encodedSignature.substring("data:image/png;base64,".length());
}

Image image = null;
try {
    byte[] decoded = Base64.getDecoder().decode(encodedSignature);
    image = Image.getInstance(decoded);
} catch (Exception e) {
    e.printStackTrace();
}
image.scaleAbsoluteHeight(fieldPosRec.getHeight());
image.scaleAbsoluteWidth(fieldPosRec.getWidth());
image.scaleToFit(fieldPosRec);
acroFields.removeField("imageField");                                              
image.setAbsolutePosition(fieldPosRec.getLeft(), fieldPosRec.getBottom());
PdfContentByte canvas = resultandPdfStamper.getOverContent(item.getPage(0));
canvas.addImage(image, Boolean.TRUE);
resultandPdfStamper.close();
resultantPdfReader.close();

共1个答案

匿名用户

您的示例图具有iText无法正确转换为内联图像的属性。不幸的是,它无法识别这一点并PDF输出错误的结果。

特别是您的图像文件使用透明度。内联图像不允许Mask或SMask条目(PDF中的图像用于表示透明度)。因此,您的图像不能用作内联图像。

因此,iText创建的内嵌图像仅包含一个黑色矩形,而透明度信息(包含线条图)被删除。

此外,您的图像使用校准的RGB颜色空间。这种校准的RGB颜色空间本身不能内联,因此必须将颜色空间定义放入页面资源中。但是,在创建内联图像时,iText无法正确引用非内联部分。

结果,iText创建的内联图像引用了错误的名称,导致Adobe Reader显示“此页上存在错误”错误消息。修复该引用会得到一个有效的结果PDF显示上面提到的黑色矩形。

在注释中,您解释说您的实际目标是防止从生成的pdf文档中复制图像。

一般来说,这显然是不可能的——PDF查看器可以访问以在屏幕或纸上绘制的任何信息也可以被一些为该任务设计的PDF处理器访问以复制到某个文件。(让我们忽略专有的、查看器特定的DRM扩展。)

不过,您可以尝试以普通PDF查看器不提供复制的方式绘制数据。尝试使用内联图像是朝这个方向发展的一种方法。其他方法将图像包装在其他结构中,例如模式:

PdfContentByte canvas = resultandPdfStamper.getOverContent(1);
Rectangle pageSize = resultantPdfReader.getPageSize(1);
PdfPatternPainter painter = canvas.createPattern(pageSize.getWidth(), pageSize.getHeight());
painter.addImage(image);
canvas.setColorFill(new PatternColor(painter));
canvas.rectangle(0, 0, pageSize.getWidth(), pageSize.getHeight());
canvas.fill();

(AddImageInPattern测试testAddToPageTest3

这里的Adobe Acrobat Reader不提供复制该图像。我的Adobe Acrobat Pro也不提供复制它,只是为了删除它(更准确地说,删除充满图案的整个矩形)。

然而,要小心,普通PDF观众做什么或不做什么是一个移动的目标…