I have a pdf file I want to use as a stamp. I’m not sure what the best approach is. Should I convert it to an image and draw it on the document? or what is the best method so it looks and acts like a stamp that acrobat would apply.
Hi Dave and sorry for the late response.
Here is a code snippet that shows how to create a custom stamp annotation:
using System;
using System.IO;
using GemBox.Pdf.Annotations;
using GemBox.Pdf.Content;
namespace GemBox.Pdf.Test.Quick
{
static partial class Program
{
static void Main()
{
var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
// For this code snippet, the PDF file to use as a stamp will be simply a copy of the input PDF file.
File.Copy(Path.Combine(desktop, "Reading.pdf"), Path.Combine(desktop, "ReadingStamp.pdf"), overwrite: true);
using (var document = PdfDocument.Load(Path.Combine(desktop, "Reading.pdf")))
{
PdfForm stampForm;
// Convert first page of the PDF file you want to use as a stamp to a form.
using (var stampDocument = PdfDocument.Load(Path.Combine(desktop, "ReadingStamp.pdf")))
stampForm = stampDocument.Pages[0].ConvertToForm(document);
// Use stampForm.SetBoundingBox() and stampForm.Transform if you want to crop or transform (for example, scale) stamp form.
var page = document.Pages[0];
var boundingBox = stampForm.BoundingBox;
// Add the Unknown (custom) stamp annotation whose size is 25% of the input PDF file page size.
var stampAnnotation = page.Annotations.AddStamp(100, 200, boundingBox.Width / 4, boundingBox.Height / 4, PdfStampIcon.Unknown);
// Set the appearance of the Stamp annotation.
stampAnnotation.Appearance.Set(stampForm);
document.Save(Path.Combine(desktop, "ReadingStamped.pdf"));
}
}
}
}
The next code snippet shows how to create a predefined stamp annotation (dynamic stamp is used because it is the most complex):
using System;
using System.Globalization;
using System.IO;
using GemBox.Pdf.Annotations;
namespace GemBox.Pdf.Test.Quick
{
static partial class Program
{
static void Main()
{
var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
using (var document = PdfDocument.Load(Path.Combine(desktop, "Reading.pdf")))
{
var page = document.Pages[0];
// Add the DynamicApproved stamp annotation with default size.
var stampAnnotation = page.Annotations.AddStamp(100, 200, 0, 0, PdfStampIcon.DynamicApproved);
// Adjust dynamic parts of the stamp annotation appearance.
stampAnnotation.Appearance.Name = "John Doe";
stampAnnotation.Appearance.Date = new DateTimeOffset(2023, 2, 14, 12, 0, 0, new TimeSpan(0, 0, 0));
stampAnnotation.Appearance.DateFormatProvider = new CultureInfo("en-US");
document.Save(Path.Combine(desktop, "ReadingStamped.pdf"));
}
}
}
}
Previous versions of GemBox.Pdf didn’t support Stamp annotations but it was possible to create them via low-level API.
Here is a code snippet that shows how to do it:
using System;
using System.IO;
using GemBox.Pdf.Content;
using GemBox.Pdf.Objects;
namespace GemBox.Pdf.Test.Quick
{
static partial class Program
{
static void Main()
{
var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
// For this code snippet, the PDF file to use as a stamp will be simply a copy of the input PDF file.
File.Copy(Path.Combine(desktop, "Reading.pdf"), Path.Combine(desktop, "ReadingStamp.pdf"), overwrite: true);
using (var document = PdfDocument.Load(Path.Combine(desktop, "Reading.pdf")))
{
PdfForm stampForm;
// Convert first page of the PDF file you want to use as a stamp to a form.
using (var stampDocument = PdfDocument.Load(Path.Combine(desktop, "ReadingStamp.pdf")))
stampForm = stampDocument.Pages[0].ConvertToForm(document);
// Use stampForm.SetBoundingBox() and stampForm.Transform if you want to crop or transform (for example, scale) stamp form.
var page = document.Pages[0];
// Get or add the underlying Annots array to the page object via low-level API.
var annots = page.Annotations.GetOrAddArray();
// Create Stamp annotation dictionary.
var stampAnnot = PdfDictionary.Create(
new PdfDictionaryEntry("Subtype", PdfName.Create("Stamp")),
new PdfDictionaryEntry("Rect", PdfArray.Create(PdfNumber.Create(100), PdfNumber.Create(200), PdfNumber.Create(300), PdfNumber.Create(400))),
new PdfDictionaryEntry("P", page.GetDictionary().Indirect));
// Set the Print flag.
// See https://opensource.adobe.com/dc-acrobat-sdk-docs/standards/pdfstandards/pdf/PDF32000_2008.pdf#page=393
stampAnnot.Add(PdfName.Create("F"), PdfInteger.Create(1 << (3 - 1)));
// Add Stamp annotation dictionary to the Annots array as an indirect object.
annots.Add(PdfIndirectObject.Create(stampAnnot));
// Access the last annotation via high-level API.
var stampAnnotation = page.Annotations[page.Annotations.Count - 1];
// Set the appearance of the Stamp annotation.
stampAnnotation.Appearance.Set(stampForm);
document.Save(Path.Combine(desktop, "ReadingStamped.pdf"));
}
}
}
}
The file used in these code snippets you can download from our example Read text from PDF files with C# / VB.NET applications
Regards,
Stipo
Hello, Thanks for the snippet. I managed to make that work but for some reason it will not print with the document. I’ve searched for a setting but can’t seem to find the right combination to get it to print.
Thanks.
Dave
Hi Dave!
You must set the Print flag in the annotation’s Flags entry (the F entry).
Please see the updated code snippet from my previous answer.
Regards,
Stipo
Thank you Stipo, I never would have found that without your help. I wish I knew more about this stuff.
Thanks to you and Mario for the great support!
Hi stipo, using your 1st sample code block works well. However, I have observed the following:
Open the resulting document in Adobe Reader. With the mouse over the 1st page, right click. The context menu that comes up, looks like this:
If you click the Properties option in that menu, this comes up :
So its like the Stamp is “active”, and the user can see its properties, and edit them via Adobe Reader etc.
Is it possible to make the stamp not editable ?
e.g. so ideally (if technically possible), when I right click on the 1st page, I will see the standard context menu, like:
Thanks
Hi,
There are two ways to disable editing of stamp properties:
- Lock the annotation:
stampAnnotation.Locked = true;
Users can still unlock it via Adobe Reader user interface.
- Make the annotation read-only (currently possible only via low-level API):
// Set the ReadOnly flag.
// See https://opensource.adobe.com/dc-acrobat-sdk-docs/standards/pdfstandards/pdf/PDF32000_2008.pdf#page=393
var stampAnnotationDictionary = stampAnnotation.GetDictionary();
var fName = PdfName.Create("F");
int f = 0;
if(stampAnnotationDictionary.TryGetValue(fName, out PdfBasicObject fValue))
{
if (fValue.ObjectType == PdfBasicObjectType.IndirectObject)
fValue = ((PdfIndirectObject)fValue).Value;
f = ((PdfInteger)fValue).Value;
}
stampAnnotationDictionary[fName] = PdfInteger.Create(f | (1 << (7 - 1)));
Users can still view stamp annotation properties but cannot edit them via Adobe Reader user interface.
The only way to disable annotation right-click context menu is to flatten the annotation (draw it directly in the page’s content) and remove it from the page’s annotation collection:
page.Content.DrawAnnotation(stampAnnotation);
page.Annotations.Remove(stampAnnotation);
Regards,
Stipo
Thanks Stipo, I ended up flattening the annotation, which worked great.