How can I associate an image with a form field?

The task I have to solve is the following:

1. Creating a template PDF document with text and image fields.
2. Storing some text and images into these fields.
3. My application has to extract values (text and images) from these
fields and be able to store its own data there.

I had created a PDF document in Adobe Designer and put few text and
image fields (interactive fields) there to be filled by user. Document
may also contain images and text which don’t have to be replaced
(such images and text should be added as not interactive image/text
fields).
Then the steps I did:
1. Created an instance of PDFDoc.
2. Used doc.FIeldBegin() + doc.FieldEnd() to enumerate all the
interactive fields.
3. Checking the type of the fields and if it is e_text then applied
the following code:
field.SetValue(Obj.CreateString("My text"));
field.RefreshAppearance();

This works perfectly but I am unable to do the same for image fields.
First, type of this field is e_button (I checked it by field’s
name – field.GetPartialName()).
Second, I cannot get a picture that is already stored in such image
field.
This task seems to be solved by using the high-level API of the PDFNet
for the interactive text fields.
But what about the image fields? Maybe it is an issue. Could you
suggest me please?

After the above investigation I tried to solve the task by using the
low-level API.
I tried to use the similar approach as in the ImageExtract example of
PDFNet, “Example 2, Extract images by scanning the low-level
document.”, then loading an additional image into the document
and swapping it by doc.Swap() method.
After the swapping I did doc.RefreshFieldAppearances().
This worked but it is not possible to distinguish the images I would
like to replace and the images I wouldn’t (using this way
enumerates all the images).
How to solve this?

So, briefly, is there a way to mark some fields (text and image) in
the document as replaceable and how to replace them using PDFNet?
-----

A:

You can associate an image with the form filed (typically an
pdftron.PDF.Field.Type.e_button) as follows:

- Set the field value to null (i.e. field.SetValue(Obj.CreateNull() or
similar).
- Set the custom appearance as follows:

if (field.IsAnnot()) {
  Annot annot = new Annot(field.GetSDFObj());
  annot.SetAppearance(CreateMyAppearance(doc));
}

Alternatively you can manually add the /AP entry in the form field
dictionary (i.e. field.GetSDFObj()).

The only remaining part is to implement CreateMyAppearance() helper
function. For example,

static Obj CreateMyAppearance(PDFDoc doc) {
  ElementBuilder build = new ElementBuilder();
  ElementWriter writer = new ElementWriter();
  writer.Begin(doc);

  Image img = Image.Create(doc, "myimage.jpg");
  int w=img.GetImageWidth(), h=img.GetImageHeight();
  Element img_element = build.CreateImage(img, 0, 0, w, h);
  writer.WritePlacedElement(img_element);
  Obj stm = writer.End();

  // Set the bounding box
  stm.Put("BBox", Rect.CreateSDFRect(0, 0, w, h));
  stm.Put("Subtype", Obj.CreateName("Form"));
  return stm;
}

The appearance stream can consist of arbitrary graphics (text, images,
vector art). For more examples of how to create custom appearances,
search for "SetAppearance" in PDFNet Knowledge Base:
  http://groups.google.com/group/pdfnet-sdk/topics

Q:

Thank you very much for the tip. It helped me a lot.
The remaining question is: how to extract an existing image from an
interactive image field?
I checked that annot.GetSDFObj() from the example you gave me is a
dictionary. Its ObjNum (according to PDFTron CosEdit) is 167. The
image I would like to extract has 170.
I have found it could be done by using the series of Obj.Find() calls
as
follows:

  Obj targ =
annot.GetSDFObj().FindObj("AP").FindObj("N").FindObj("Resources").FindOb
j("XObject").

FindObj("FRM").FindObj("Resources").FindObj("XObject").FindObj("Im0");
  pdftron.PDF.Image image = new pdftron.PDF.Image(targ);

:slight_smile: As you probably understand the knowledge about the structure has
been obtained by CosEdit.

So is there a way to do it by a "better" way? Could you suggest me
please?
-----
A:

So is there a way to do it by a "better" way?

To extract images from form fields you could also use the following
pseudocode:

if (field.IsAnnot()) {
  Annot annot = new Annot(field.GetSDFObj());
  Obj app_stm = annot.GetAppearance();
  if (app_stm != null) {
       ElementReader reader = new ElementReader();
       reader.Begin(app_stm);
       //... You may also need to recursively process form XObjects
       ProcessElement(reader); // See ElementReader and ImageExtract
sample projects for
       // an example of how to use implement this function
       reader.End()
   }
}

You may also want to take a look at the following article in PDFNet
Knowledge Base:
  http://groups.google.com/group/pdfnet-sdk/browse_thread/thread/de8fdd43cf4aa6ef/4ff2df6820b1046f