是否可以用开放源码软件库pdfbox提取已签名PDF的可见签名(图像)?
工作流:
像下面这样的oop风格的东西会很棒:
PDFSignatures [] sigs = document.getPDFSignatures()
sig[0].getCN()
...
(Buffered)Image visibleSig = sig[0].getVisibleSignature()
找到了类PDSignature和如何签署一个PDF,但没有解决方案提取一个可见的签名作为图像。
由于没有人上来回答,我自己在对你的问题的评论中尝试了我的建议。第一个结果:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdfviewer.PageDrawer;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.PDGraphicsState;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
public class AnnotationDrawer extends PageDrawer
{
public AnnotationDrawer(int imageType, int resolution) throws IOException
{
super();
this.imageType = imageType;
this.resolution = resolution;
}
public Map<String, BufferedImage> convertToImages(PDPage p) throws IOException
{
page = p;
final Map<String, BufferedImage> result = new HashMap<String, BufferedImage>();
List<PDAnnotation> annotations = page.getAnnotations();
for (PDAnnotation annotation: annotations)
{
String appearanceName = annotation.getAppearanceStream();
PDAppearanceDictionary appearDictionary = annotation.getAppearance();
if( appearDictionary != null )
{
if( appearanceName == null )
{
appearanceName = "default";
}
Map<String, PDAppearanceStream> appearanceMap = appearDictionary.getNormalAppearance();
if (appearanceMap != null)
{
PDAppearanceStream appearance =
(PDAppearanceStream)appearanceMap.get( appearanceName );
if( appearance != null )
{
BufferedImage image = initializeGraphics(annotation);
setTextMatrix(null);
setTextLineMatrix(null);
getGraphicsStack().clear();
processSubStream( page, appearance.getResources(), appearance.getStream() );
String name = annotation.getAnnotationName();
if (name == null || name.length() == 0)
{
name = annotation.getDictionary().getString(COSName.T);
if (name == null || name.length() == 0)
{
name = Long.toHexString(annotation.hashCode());
}
}
result.put(name, image);
}
}
}
}
return result;
}
BufferedImage initializeGraphics(PDAnnotation annotation)
{
PDRectangle rect = annotation.getRectangle();
float widthPt = rect.getWidth();
float heightPt = rect.getHeight();
float scaling = resolution / (float)DEFAULT_USER_SPACE_UNIT_DPI;
int widthPx = Math.round(widthPt * scaling);
int heightPx = Math.round(heightPt * scaling);
//TODO The following reduces accuracy. It should really be a Dimension2D.Float.
Dimension pageDimension = new Dimension( (int)widthPt, (int)heightPt );
BufferedImage retval = new BufferedImage( widthPx, heightPx, imageType );
Graphics2D graphics = (Graphics2D)retval.getGraphics();
graphics.setBackground( TRANSPARENT_WHITE );
graphics.clearRect( 0, 0, retval.getWidth(), retval.getHeight() );
graphics.scale( scaling, scaling );
setGraphics(graphics);
pageSize = pageDimension;
graphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
graphics.setRenderingHint( RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON );
setGraphicsState(new PDGraphicsState(new PDRectangle(widthPt, heightPt)));
return retval;
}
void setGraphics(Graphics2D graphics)
{
try {
Field field = PageDrawer.class.getDeclaredField("graphics");
field.setAccessible(true);
field.set(this, graphics);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static final int DEFAULT_USER_SPACE_UNIT_DPI = 72;
private static final Color TRANSPARENT_WHITE = new Color( 255, 255, 255, 0 );
private int imageType;
private int resolution;
}
如果要呈现给定PDPage页的批注,
只需执行以下操作:
AnnotationDrawer drawer = new AnnotationDrawer(8, 288);
Map<String, BufferedImage> images = drawer.convertToImages(page);
构造函数参数与pdpage.convertToImage(int imageType,int resolution)的参数相对应。
a.基于PDFBox 1.8.2一起被黑;它可能包含特定于版本的代码;b.只是检查了我这里的一些可见的签名注释;它可能是不完整的,对于其他批注类型,它尤其可能失败。
链接到pdf 当我尝试从上面的pdf中提取文本时,我得到了在evince viewer中不可见的文本和可见的文本的混合。此外,一些所需的文本缺少查看器中没有缺少的字符,例如,“FALCONS”中的“S”和许多缺少的“½”字符。我认为这是由于不可见文本的干扰,因为在查看器中突出显示pdf时,可以看到不可见文本与可见文本重叠。 有没有办法去掉不可见的文字?还是有别的解决办法? 代码: 输出(粗体文本为
问题内容: 链接到pdf 当我尝试从上面的pdf中提取文本时,我混合了在evince查看器中不可见的文本和可见的文本。此外,某些所需的文本缺少查看器中未缺少的字符,例如“ FALCONS”中的“ S”和许多缺少的“ 1/2”字符。我认为这是由于来自不可见文本的干扰,因为在查看器中突出显示pdf时,可以看到不可见文本与可见文本重叠。 有没有办法删除不可见的文字?还是有其他解决方案? 码: 输出(粗体
我有一个场景,我需要用iText7库从pdf中获取签名信息。签名可能存在,也可能不存在。当我为没有任何数字签名的PDF实例化一个新的对象时,会出现异常 “没有相关的PdfWriter用于进行间接操作。” .如果有签名,就很好用。我不确定如何纠正这个异常。 更新为包含代码示例
我正在尝试使用pdfbox库签署pdf。我现在卡住了,真的需要帮助。 这是我的代码: 然后我正在保存我的pdf,但是:1)我注意到sign method从来没有被调用2)我应该在哪里附加CertyFicate?在sign method中? 以下是我保存PDF的方法:
我想从现有的pdf中获取图像字段,并用其他图像填充它,以使用java中的pdfbox库创建新的pdf文件
我正在从PDF中删除一个带有书签链接的页面。删除页面后,指向此页面的书签链接不再有效。 我没有从PDFBox api中找到一种方法来完成这项工作 有没有办法删除这个书签?有没有办法删除全部书签? 提前感谢