Rank: Newbie
Groups: Registered
Joined: 1/11/2023(UTC) Posts: 7 
|
One of our requirements for processing our data into PDFs is to place images in pre-defined locations. Using other PDF libraries, using a button field and changing the icon has always been the simplest way. The button allows for the icon properties to be pre-defined. Then the processing engine only needs to swap out the icon on the button. Then the image is already in the correct place and size on the page. Is this achievable with the Patagames Pdfium SDK?
The whole process is this: -Open a template page -Fill in form fields -Add annotation text -Place images in pre-defined locations*** -Set the page label -Merge the template page into the output document -Repeat for N pages...
Right now I am hung up on inserting the images.
|
|
|
|
Rank: Administration
Groups: Administrators
Joined: 1/5/2016(UTC) Posts: 1,080
Thanks: 6 times Was thanked: 126 time(s) in 123 post(s)
|
Hello, Here is the acroforms documentation to understand how to access/create/manipulate buttons and other forms. https://pdfium.patagames...WorkingSDK_AcroForms.htmAnd here is an example of how to create a button with an icon. Code:
using (var doc = PdfDocument.CreateNew(new PdfForms()))
{
//Set default appearance. Helvetica and autosize is used by default
if (!doc.FormFill.InterForm.HasDefaultAppearance())
doc.FormFill.InterForm.SetDefaultAppearance();
//Create a pushbutton field
var pushbuttonField = new PdfPushButtonField(doc.FormFill.InterForm);
//Create a pushbutton control that uses default appearance.
var page = doc.Pages.InsertPageAt(0, 500, 500);
var icon = PdfBitmap.FromFile(@"e:\0\stamp.jpg");
var btnRect = new FS_RECTF(10, page.Height - 10, 10 + icon.Width, page.Height - 10 - icon.Height);
var pushbuttonCtrl = new PdfPushButtonControl(pushbuttonField, page, btnRect, "Button caption", null, null, null, null, null, 0, icon, FormHighlightingMode.Push, TextPositions.TEXTPOS_ICON);
//Add the form field to the document.
doc.FormFill.InterForm.Fields.Add(pushbuttonField);
//Save the document
doc.Save(@"e:\22\test.pdf", Patagames.Pdf.Enums.SaveFlags.NoIncremental);
}
And here's how to change the icon on an existing button. Code:
using (var doc = PdfDocument.Load(@"e:\22\test.pdf", new PdfForms()))
{
var pushbuttonField = doc.FormFill.InterForm.Fields[0];
var pushbuttonCtrl = pushbuttonField.Controls[0];
var widget = pushbuttonCtrl.GetWidget();
var page = widget.Page;
var icon = PdfBitmap.FromFile(@"e:\0\logo_square.png");
widget.MK.NormalIcon.Clear();
widget.MK.NormalIcon.Add(PdfImageObject.Create(doc, icon, 0, 0));
widget.MK.GenerateAppearance(AppearanceStreamModes.Normal);
//Save the document
doc.Save(@"e:\22\test2.pdf", Patagames.Pdf.Enums.SaveFlags.NoIncremental);
}
|
|
|
|
Rank: Newbie
Groups: Registered
Joined: 1/11/2023(UTC) Posts: 7 
|
I thank you for your response. That is pretty one of the ways that I tried to implement the desired behavior. However, if I implement it exactly as you have it, "widget.MK.NormalIcon" throws a "KeyNotFoundException". To overcome this, I made a call to "widget.MK.CreateEmptyAppearance(AppearanceStreamModes.Normal);" This allowed the code to proceed, but the results are not what is expected. The shows up way too large on the button, even though the original template file had "Fit To Bounds" option checked for the button icon. If I return to the form button icon properties in the output document, that option is still checked. Then when I close the options, the image scales to the correct size of the button. Another observation: The original template file is 3.8 MB, the image is 3 MB, and the output after executing this code is 24MB. Why is the result document so large? Is there a way to have it downsample the image? Code:
[Test]
public void TestSetButtonIcon()
{
PdfCommon.Initialize(License);
var form = new PdfForms();
using (var doc = PdfDocument.Load(PdfTestHelper.TemplatePath, form))
{
foreach (var pdfField in doc.FormFill.InterForm.Fields.OfType<PdfPushButtonField>())
{
if (pdfField.FullName == "image_context")
{
if (pdfField.Controls[0] is PdfPushButtonControl control)
{
var widget = control.GetWidget();
using (var bitmap = PdfBitmap.FromFile("Test Files/1d40e024-6bce-4b72-9502-18a104c5b968.jpg"))
{
var pdfImageObject = PdfImageObject.Create(doc, bitmap, 0, 0);
widget.MK.CreateEmptyAppearance(AppearanceStreamModes.Normal);
widget.MK.NormalIcon.Clear();
widget.MK.NormalIcon.Add(pdfImageObject);
widget.MK.GenerateAppearance(AppearanceStreamModes.Normal);
}
}
}
}
doc.Save("test_output.pdf", SaveFlags.NoIncremental);
}
}
|
|
|
|
Rank: Administration
Groups: Administrators
Joined: 1/5/2016(UTC) Posts: 1,080
Thanks: 6 times Was thanked: 126 time(s) in 123 post(s)
|
First of all, update to the latest version (4.78.2704) which fixed a couple of issues related to your task. https://forum.patagames....released-on-Jan-13--2023Originally Posted by: bav  "widget.MK.NormalIcon" throws a "KeyNotFoundException".
this issue has been fixed, but calling the CreateEmptyAppearance method is more welcome. Quote: The shows up way too large on the button, even though the original template file had "Fit To Bounds" option checked for the button icon.
A Widget annotation has its own appearance stream, which is generated based on the properties of this annotation, including the group of MK properties. Therefore, you need to regenerate such a stream, as shown in the example below. Quote: The original template file is 3.8 MB, the image is 3 MB, and the output after executing this code is 24MB. Why is the result document so large? Is there a way to have it downsample the image?
A way to reduce the size of the resulting file is to use jpeg instead of PdfBitmap, where each pixel is represented by four bytes. You can also use these saving flags: Code:SaveFlags.NoIncremental | SaveFlags.ObjectStream | SaveFlags.RemoveUnusedObjects
Code:
public static void TestSetButtonIcon()
{
using (var doc = PdfDocument.Load(@"e:\22\test.pdf", new PdfForms()))
{
foreach (var pdfField in doc.FormFill.InterForm.Fields.OfType<PdfPushButtonField>())
{
if (pdfField.FullName == "image_context")
{
if (pdfField.Controls[0] is PdfPushButtonControl control)
{
string imgFile = @"e:\19\d66ae37d46e00a1ecacfe9531986690a-9ba9622-2.jpg";
var widget = control.GetWidget();
//Create an empty image object
var pdfImageObject = PdfImageObject.Create(doc);
//Initiate it with a joeg file in order to reduce the image size
//(use packed jpeg instead of bitmap mask when the PdfBitmap is used)
pdfImageObject.LoadJpegFile(imgFile);
//Set the image Matrix
pdfImageObject.Matrix = new FS_MATRIX(pdfImageObject.Bitmap.Width, 0, 0, pdfImageObject.Bitmap.Height, 0, 0);
//Create/recreate the appearance stream
widget.MK.CreateEmptyAppearance(AppearanceStreamModes.Normal);
widget.MK.NormalIcon.Add(pdfImageObject);
widget.MK.GenerateAppearance(AppearanceStreamModes.Normal);
//The widget has its own appearance stream, which was generated based on the MK.
//Since we have changed the icon in MK, we also need to regenerate the appearance stream of this widget.
pdfField.Controls[0].RegenerateAppearance();
}
}
}
doc.Save(@"e:\22\test_output.pdf", SaveFlags.NoIncremental | SaveFlags.ObjectStream | SaveFlags.RemoveUnusedObjects);
}
}
Edited by user Friday, January 13, 2023 2:23:54 AM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Newbie
Groups: Registered
Joined: 1/11/2023(UTC) Posts: 7 
|
Thank you, that seemed to have solved my issue with setting the button icon image. I was missing setting the PdfImageObject matrix and regenerating the appearance on the control.
|
|
|
|
Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.
Important Information:
The Patagames Software Support Forum uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close