How do I set image/PDF as a value of a button form field?

139 views
Skip to first unread message

Support

unread,
May 21, 2008, 9:40:43 PM5/21/08
to PDFTron PDFNet SDK
Q: We use forms buttons as place holders for showing graphical PDFs.
This allows our form designers to sort of have a WSIWIG of where the
graphics will appear on a form. The buttons are set to ICON ONLY and
READ ONLY. How do I set a button to display a PDF via PDFNet? I am
assuming it’s something like a watermark using streams and writers. I
can’t seem to find any sample code on how this can be achieved.

--------
A: What you want to do is to define a custom appearance for a widget
annotation (i.e. a button).

To create your own icon for stamp annotation you would need to create
a custom appearance using ElementBuilder & ElementWriter. Then you can
use annot.SetAppearance() to associate the new appearance with an
annotation.

For examples of how to create custom appearances, you may want to
search PDFNet KB using the following keyword: "SetAppearance".

The code may look along the following lines:

// Create appearance stream for the annotation -------- ElementWriter
writer = new ElementWriter(); ElementBuilder eb = new
ElementBuilder(); writer.Begin(pdfdoc);

Element element = builder.CreateForm(input_pdf_page, pdfdoc); double
scale_x = input_pdf_page.GetPageWidth(); double scale_y =
input_pdf_page.GetPageHeight();
element.GetGState().SetTransform(scale_x, 0, 0, scale_y, offset_x,
offset_y); writer.WritePlacedElement(element);
writer.WriteElement(element);

Obj appearance_stream = writer.End();

// Set the annotation appearance...
myannot.SetAppearance(appearance_stream)

Support

unread,
May 21, 2008, 9:42:23 PM5/21/08
to PDFTron PDFNet SDK
Q: Thanks for your advice. I looked up this information and based on
what I could find, this is what I came up with. Problem is, it imports
the PDF on the page (in the lower right corner... this is not what I
want) and my button is always blank. I'm not too sure what more I have
to do. What I need is to import the PDF so it appears ONLY in the
button and nowhere else. I'm not too sure how to go about doing this.
I'm hoping you could tell me where I'm going wrong. Here is my sample
code.

static void Main(string[] args)
{
PDFNet.Initialize();
PDFNet.SetResourcesPath("../../../../../resources");

// Relative path to the folder containing test files.
string input_path = "C:\\a\\TestFiles\\";
string output_path = "C:\\a\\TestFiles\\Output\\";

Int32 pageCount = 1;

try
{
PDFDoc template = new PDFDoc(input_path +
"template.pdf");
template.InitSecurityHandler();

PDFDoc new_PDF = new PDFDoc();

//Create as many pages as we need...
for (int loop = 1; loop <= pageCount; loop++)
{
new_PDF.PagePushBack(template.GetPage(1));
}

// Rename fields as 'fieldname_pagecount ie: Text1_1
RenameAllFields(new_PDF, pageCount);

//Now ww loop through all pages and set field and
button values...
Field fld = null;
for (int loop = 1; loop <= pageCount; loop++)
{
fld = new_PDF.GetField("Text1_" +
loop.ToString());
if (fld != null)
{
fld.SetValue("Page " + loop.ToString());
}

fld = new_PDF.GetField("Text3_" +
loop.ToString());
if (fld != null)
{
fld.SetValue("*Hello" + loop.ToString() +
"*");
}

#region Insert PDF on a Button

PDFDoc import_PDF = new PDFDoc(input_path +
"reflect3.pdf");
import_PDF.InitSecurityHandler();

Rect media_box = new Rect(0, 0, 100, 100);
double mid_point = media_box.Width();

ElementBuilder builder = new ElementBuilder();
ElementWriter writer = new ElementWriter();

writer.Begin(new_PDF.GetPageIterator().Current());
Page import_Page = import_PDF.GetPage(1);
Element element = builder.CreateForm(import_Page,
new_PDF);

double sc_x = mid_point /
import_Page.GetPageWidth();
double sc_y = media_box.Height() /
import_Page.GetPageHeight();
double scale = Math.Min(sc_x, sc_y);

element.GetGState().SetTransform(scale, 0, 0,
scale, 0, 0);

//writer.WritePlacedElement(element); // This
causes cannot find object 'FM0' in reader...
writer.WriteElement(element);

Obj appearance_stream = writer.End();

// Set the button appearance...
Annot button = new
Annot(new_PDF.GetField("Button1_1").GetSDFObj());
button.SetAppearance(appearance_stream);

#endregion
}

// Regenerate field appearances...
new_PDF.RefreshFieldAppearances();

// Save new PDF...
new_PDF.Save(output_path + "Output.pdf",
SDFDoc.SaveOptions.e_linearized);

template.Close();
new_PDF.Close();
}

catch (PDFNetException e)
{
Console.WriteLine(e.Message);
}
PDFNet.Terminate();
}

Support

unread,
May 21, 2008, 9:44:49 PM5/21/08
to PDFTron PDFNet SDK
A: The problem seems to be related to positioning of the image within
the annotation bounding box (there was another error where you were
writing the appearance stream on the page instead of the separate
const stream). In any case you can find all the modifications and a
working test project in the attachment.

using System;
using pdftron;
using pdftron.Common;
using pdftron.SDF;
using pdftron.PDF;
using System.Collections;

namespace SpecPrinting
{
/// <summary>
/// Make a multi-page PDF using an existing PDF as a template.
/// </summary>
class Class1
{
static void Main(string[] args)
{
PDFNet.Initialize();
PDFNet.SetResourcesPath("../../../../../Resources");

// Relative path to the folder containing test files.
string input_path = "D:\\_TESTME\\";
string output_path = "D:\\_TESTME\\";

Int32 pageCount = 1;

try
{
PDFDoc template = new PDFDoc(input_path + "05ML.pdf");
template.InitSecurityHandler();

PDFDoc new_PDF = new PDFDoc();

//Create as many pages as we need...
for (int loop = 1; loop <= pageCount; loop++)
{
new_PDF.PagePushBack(template.GetPage(1));
}

// Rename fields as 'fieldname_pagecount ie: Text1_1
RenameAllFields(new_PDF, pageCount);


//Set field values...
Field fld = null;
for (int loop = 1; loop <= pageCount; loop++)
{
fld = new_PDF.GetField("CUSTOMER_DESCR_" + loop.ToString());
if (fld != null)
{
fld.SetValue("LABATT BREWERIES OF CANADA");
}

fld = new_PDF.GetField("CUSTPROD_" + loop.ToString());
if (fld != null)
{
fld.SetValue("8300 710 ML BUD");
}

// You get the idea...

// Regenerate field appearances otherwise we won't see field
values...
new_PDF.RefreshFieldAppearances();


#region Insert design spec PDF on a Button

Annot button = new
Annot(new_PDF.GetField("DESSIN_1").GetSDFObj());

PDFDoc import_PDF = new PDFDoc(input_path +
"028550_000605_00003.pdf");
import_PDF.InitSecurityHandler();

ElementBuilder builder = new ElementBuilder();
ElementWriter writer = new ElementWriter();

writer.Begin(new_PDF);
Page import_Page = import_PDF.GetPage(1);
Element element = builder.CreateForm(import_Page, new_PDF);
element.GetGState().SetTransform(1, 0, 0, 1, 0, 0);
writer.WritePlacedElement(element);

Obj appearance_stream = writer.End();

// Set the bounding box
Rect bbox = button.GetRect();

double sc_x = bbox.Width() / import_Page.GetPageWidth();
double sc_y = bbox.Height() / import_Page.GetPageHeight();
double scale = Math.Min(sc_x, sc_y);

appearance_stream.PutRect("BBox", 0, 0,
import_Page.GetPageWidth(), import_Page.GetPageHeight());
appearance_stream.PutMatrix("Matrix", new Matrix2D(scale, 0, 0,
scale, 0, 0));
appearance_stream.PutName("Subtype", "Form");

// Set the button appearance...
button.SetAppearance(appearance_stream);

#endregion
}

// Save new PDF...
new_PDF.Save(output_path + "Output.pdf",
SDFDoc.SaveOptions.e_linearized);

template.Close();
new_PDF.Close();
}

catch (PDFNetException e)
{
Console.WriteLine(e.Message);
}
PDFNet.Terminate();
}

static void RenameAllFields(PDFDoc doc, String name)
{
Field fld = doc.GetField(name);
for (int counter = 1; fld != null; ++counter)
{
fld.Rename(name + "_" + counter.ToString());
fld = doc.GetField(name);
}
}

static void RenameAllFields(PDFDoc doc, Int32 count)
{
Hashtable FormFields = new Hashtable();
FieldIterator itr;

int hashIndex = 0;

// Load hash table to identify each unique field in the form...
for (itr = doc.GetFieldIterator(); itr.HasNext(); itr.Next())
{
try
{
hashIndex = (int)FormFields[itr.Current().GetName()];
}
catch (NullReferenceException)
{
FormFields.Add(itr.Current().GetName(), 0);
}
}

// Enumerate the hash table and rename all occurrences via a
loop...
IDictionaryEnumerator hashEnumerator = FormFields.GetEnumerator();
while (hashEnumerator.MoveNext())
{
for (int loop = 1; loop <= count; loop++)
{
Field fld = doc.GetField(hashEnumerator.Entry.Key.ToString());
fld.Rename(hashEnumerator.Entry.Key.ToString() + "_" +
loop.ToString());
}
}
}
}
}
Reply all
Reply to author
Forward
0 new messages