我们有一个用户用来生成某些报告的ASP.NET应用程序。到目前为止,我们有一个PDF模板,上面有一个图像,我们只需用编程生成的图像(图形)替换该图像。
我们使用了本网站的代码:http://blog.rubypdf.com/2007/12/12/how-to-replace-images-in-a-pdf/
现在问题是我们在一个PDF页面上有两个不同的图像,上面链接的代码在一个页面上选择两个图像,并用我们生成的图像一次性替换它们。
有没有人知道如何用itext替换一页上的多个不同图像?
由于
答案 0 :(得分:8)
唉。首先,让我重写一些来源。
PdfReader pdf = new PdfReader("in.pdf");
PdfStamper stp = new PdfStamper(pdf, new FileOutputStream("c:\\out.pdf"));
PdfWriter writer = stp.getWriter();
Image img = Image.getInstance("image.png");
PdfDictionary pg = pdf.getPageN(1);
PdfDictionary res = pg.getAsDict.get(PdfName.RESOURCES);
PdfDictionary xobj = res.getAsDict(PdfName.XOBJECT);
if (xobj != null) {
for (Iterator<PdfName> it = xobj.getKeys().iterator(); it.hasNext(); ) {
PdfObject obj = xobj.get(it.next());
if (obj.isIndirect()) {
PdfDictionary tg = (PdfDictionary)PdfReader.getPdfObject(obj);
PdfName type = tg.getAsName(PdfName.SUBTYPE));
if (PdfName.IMAGE.equals(type)) {
PdfReader.killIndirect(obj);
Image maskImage = img.getImageMask();
if (maskImage != null)
writer.addDirectImageSimple(maskImage);
writer.addDirectImageSimple(img, (PRIndirectReference)obj);
break;
}
}
}
}
呼。 getAs
函数可以为您节省大量的润滑油,让您的代码更清晰。
现在。您需要能够区分各种图像。如果你愿意对事物进行硬编码,你可以找出资源名称是什么,然后走这条路:
String imageResName[] = {"Img1", "Img2" ... };
Image img[] = {Image.getInstance("foo.png"), Image.getInstance("bar.png"), ... };
for (int i = 0; i < imageResName.length; ++i) {
PdfName curKey = new PdfName(imageResName[i]);
PdfIndirectReference ref = xobj.getAsIndirect(curKey);
PdfReader.killIndirect( ref );
Image maskImage = img[i].getImageMask();
if (maskImage != null) {
writer.addDirectImageSimple(maskImage);
}
writer.addDirectImageSimple(img[i], (PRIndirectReference)ref);
}
如果您不愿意使用硬编码的资源名称(并且没有人会对您造成错误,恰恰相反,特别是当它们出现的顺序(以及最后的数字)取决于它们在哈希映射中的顺序时... [颤抖]),您可以根据图像的宽度和高度进行区分。
//keep the original for loop, stepping through resource names
if (PdfName.IMAGE.equals(type)) {
float width = tg.getAsNumber(PdfName.WIDTH).floatValue();
float height = tg.getAsNumber(PdfName.HEIGHT).floatValue();
Image img = getImageFromDimensions(width, height);
Image maskImage = img.getImageMask();
...
}
答案 1 :(得分:2)
请注意,有时图像将嵌套在一个表单中,因此创建一个将递归调用的函数是明智的。 像这样:
public void StartHere()
{
PdfReader pdf = new PdfReader("in.pdf");
PdfStamper stp = new PdfStamper(pdf, new FileOutputStream("c:\\out.pdf"));
PdfWriter writer = stp.getWriter();
Image img = Image.getInstance("image.png");
PdfDictionary pg = pdf.getPageN(1);
replaceImage(pg, writer,img);
}
private void replaceImage(PdfDictionary pg, PdfWriter writer,Image img)
{
PdfDictionary res = pg.getAsDict.get(PdfName.RESOURCES);
PdfDictionary xobj = res.getAsDict(PdfName.XOBJECT);
if (xobj != null) {
for (Iterator<PdfName> it = xobj.getKeys().iterator(); it.hasNext(); ) {
PdfObject obj = xobj.get(it.next());
if (obj.isIndirect()) {
PdfDictionary tg = (PdfDictionary)PdfReader.getPdfObject(obj);
PdfName type = tg.getAsName(PdfName.SUBTYPE));
if (PdfName.IMAGE.equals(type))
{
PdfReader.killIndirect(obj);
Image maskImage = img.getImageMask();
if (maskImage != null)
writer.addDirectImageSimple(maskImage);
writer.addDirectImageSimple(img, (PRIndirectReference)obj);
break;
}
else if(PdfName.FORM.equals(type))
{
replaceImage(tg, writer,img);
}
}
}
}