使用itext替换一个PDF模板页面上的多个不同图像(itextsharp)

时间:2010-11-29 08:39:53

标签: asp.net image templates pdf itextsharp

我们有一个用户用来生成某些报告的ASP.NET应用程序。到目前为止,我们有一个PDF模板,上面有一个图像,我们只需用编程生成的图像(图形)替换该图像。
我们使用了本网站的代码:http://blog.rubypdf.com/2007/12/12/how-to-replace-images-in-a-pdf/

现在问题是我们在一个PDF页面上有两个不同的图像,上面链接的代码在一个页面上选择两个图像,并用我们生成的图像一次性替换它们。

有没有人知道如何用itext替换一页上的多个不同图像?

由于

2 个答案:

答案 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);
          }
        }
      }
    }
相关问题