Java 如何在使用iText7将图像添加到PDFButtonFormField时保持纵横比

Java 如何在使用iText7将图像添加到PDFButtonFormField时保持纵横比,java,image,pdf,itext,Java,Image,Pdf,Itext,我正在收集PDF表单上带有表单字段的用户的图像。当该字段为空时,用户可以在Acrobat中填充该字段,我可以使用iText7从表单中成功读取该字段。如果用户以前上传过图像,我希望向他们展示已添加到表单字段中的图像,并允许他们选择和提交不同的图像。iText允许我用图像填充表单,但我将图像的纵横比调整为表单字段矩形的尺寸,从而扭曲了图像的纵横比 有没有办法让iText的setImage()方法在加载图像时保持纵横比 在加载图像之前,我还尝试使用以下代码修改表单字段的矩形,以符合图像纵横比: Pdf

我正在收集PDF表单上带有表单字段的用户的图像。当该字段为空时,用户可以在Acrobat中填充该字段,我可以使用iText7从表单中成功读取该字段。如果用户以前上传过图像,我希望向他们展示已添加到表单字段中的图像,并允许他们选择和提交不同的图像。iText允许我用图像填充表单,但我将图像的纵横比调整为表单字段矩形的尺寸,从而扭曲了图像的纵横比

有没有办法让iText的
setImage()
方法在加载图像时保持纵横比

在加载图像之前,我还尝试使用以下代码修改表单字段的矩形,以符合图像纵横比:

PdfReader reader = new PdfReader("TestForm.pdf");
ByteArrayOutputStream os = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(os);
StampingProperties properties = new StampingProperties();
properties.useAppendMode();
PdfDocument document = new PdfDocument(reader, writer, properties);
PdfAcroForm acroForm = PdfAcroForm.getAcroForm(document, false);
acroForm.setNeedAppearances(true);

//  get button form field
String fieldName = "Image1_af_image";
PdfButtonFormField field = (PdfButtonFormField)acroForm.getField(fieldName);
//  retrieve widget rectangle
PdfDictionary widgets = field.getWidgets().get(0).getPdfObject();
com.itextpdf.kernel.geom.Rectangle rect = widgets.getAsRectangle(PdfName.Rect);
//  modify its width
field.setImage("/Users/sschultz/Desktop/zuni logo.jpg").setFieldName(fieldName);

document.close();
os.flush();
os.close();
FileUtils.writeByteArrayToFile(new File("TestForm_out.pdf"), os.toByteArray());
但此代码无法修改表单字段的原始维度

最后,我尝试添加第二个具有适当纵横比的新表单字段:

//  add second button field to form
String fieldName2 = "Image2_af_image";
PdfButtonFormField imageField = PdfFormField.createButton(document, new Rectangle(10, 10, 200, 50),
        PdfButtonFormField.FF_PUSH_BUTTON);
imageField.setImage("image2.jpg").setFieldName(fieldName2);
acroForm.addField(imageField);

但是第二个字段从未出现在表单中。

绘图按钮字段外观的默认行为不保留图像的纵横比,覆盖起来相当复杂。相反,我可以建议手动生成外观,使其完全符合您的需要

// get widget dictionary
List<PdfWidgetAnnotation> widgets = pushButtonField.getWidgets();
PdfDictionary widgetDict;
if (widgets.size() > 0) {
    widgetDict = widgets.get(0).getPdfObject();
} else {
    // widgets.size() == 0 shouldn't really happen to properly created
    // existing fields, but let's do it just in case
    widgetDict = pushButtonField.getPdfObject();
}
Rectangle origRect = widgetDict.getAsRectangle(PdfName.Rect);
float borderWidth = pushButtonField.getBorderWidth();

String imgPath = ... // path to image file

// draw custom appearance preserving original field sizes
PdfFormXObject pdfFormXObject = new PdfFormXObject(new Rectangle(origRect.getWidth() - borderWidth * 2, origRect.getHeight() - borderWidth * 2));
Canvas canvas = new Canvas(pdfFormXObject, pdfDoc);
// Image class preserves aspect ratio by default
Image image = new Image(ImageDataFactory.create(imgPath))
        .setAutoScale(true)
        .setHorizontalAlignment(HorizontalAlignment.CENTER);
Div container = new Div()
        .setMargin(borderWidth).add(image)
        .setVerticalAlignment(VerticalAlignment.MIDDLE)
        .setFillAvailableArea(true);
canvas.add(container);
canvas.close();

// override original appearance with new one
PdfDictionary apDict = new PdfDictionary();
widgetDict.put(PdfName.AP, apDict);
apDict.put(PdfName.N, pdfFormXObject.getPdfObject());

// mark widgetDict as modified in order to save its changes in append mode
widgetDict.setModified();
//获取小部件字典
List widgets=pushButtonField.getWidgets();
PdfDictionary widgetDict;
if(widgets.size()>0){
widgetDict=widgets.get(0.getPdfObject();
}否则{
//widgets.size()==0实际上不应该正确创建
//现有字段,但让我们这样做只是以防万一
widgetDict=pushButtonField.getPdfObject();
}
矩形origRect=widgetDict.getAsRectangle(PdfName.Rect);
float borderWidth=pushButtonField.getBorderWidth();
字符串imgPath=…//图像文件的路径
//绘制保留原始字段大小的自定义外观
PdfFormXObject PdfFormXObject=新的PdfFormXObject(新矩形(origRect.getWidth()-borderWidth*2,origRect.getHeight()-borderWidth*2));
画布画布=新画布(pdfFormXObject,pdfDoc);
//默认情况下,Image类保留纵横比
Image Image=新映像(ImageDataFactory.create(imgPath))
.setAutoScale(真)
.setHorizontalAlignment(HorizontalAlignment.CENTER);
Div容器=新Div()
.setMargin(边框宽度).add(图像)
.设置垂直对齐(垂直对齐.中间)
.setFillAvailableArea(真);
canvas.add(容器);
canvas.close();
//用新外观替代原始外观
PdfDictionary apDict=新的PdfDictionary();
widgetDict.put(PdfName.AP,apDict);
apDict.put(PdfName.N,pdfFormXObject.getPdfObject());
//将widgetDict标记为已修改,以便在追加模式下保存其更改
widgetDict.setModified();
如果您使用的是
properties.useAendMode(),则所有低级
PdfObject
s修改都需要执行最后一行(调用
setModified()
。否则,将不保存更改