Use vector stamps instead of blurry shapes

Use vector stamps instead of blurry shapes

Stamp annotations are the digital equivalent of rubber stamps in the office. Since stamps can contain both images and text/graphics, they’re essentially a PDF inside your PDF, which is called an appearance stream. Nutrient has always included support for a large set of default stamps, in addition to including support for image-based stamps and stamps with customized text.

With Nutrient Android SDK 4.1 and Nutrient iOS SDK 7.1, we’re now unlocking the full power of stamp annotations with our brand-new API for appearance streams. This allows you to define custom stamps — such as shapes, logos, or markers — in vector format.

Vector Stamps

A flexible API

Vector stamps have been a long-requested feature by many of our partners. A vector stamp palette populated with custom shapes allows users to place high-quality markers that are specific to their use cases without increasing the file size the way bitmap stamps would.

Unlike image stamp annotations, vector stamp annotations allow transparency and high-resolution zoom.

Bitmap StampVector Stamp

The API has been designed in a generic way and is not limited to stamp annotations. Custom appearance streams can be added to ink, free text, and other compatible annotation types.

Create a vector stamp programmatically

You can create a vector stamp annotation by using the appearance stream generator with the URL of a PDF file. You can use any document, and Nutrient will automatically use the first page as annotation content. The SDK also provides basic generators that allow you to create such PDFs.

The sections below outline how this looks in code.

Android

// Create a new stamp annotation using the appearance stream generator.
val stampAnnotation = StampAnnotation(pageIndex, RectF(300f, 500f, 500f, 300f), "Stamp with custom AP stream")
// Create the appearance stream generator from the URL of a PDF file.
val logoUri = Uri.fromFile("path/to/your/logo.pdf")
stampAnnotation.appearanceStreamGenerator = ContentResolverAppearanceStreamGenerator(logoUri)
// Add the newly created annotation to the document.
document.getAnnotationProvider().addAnnotationToPage(stampAnnotation)
// Create a new stamp annotation using the appearance stream generator.
StampAnnotation stampAnnotation = new StampAnnotation(pageIndex, new RectF(300f, 500f, 500f, 300f), "Stamp with custom AP stream");
// Create the appearance stream generator from the URL of a PDF file.
Uri logoUri = Uri.fromFile("path/to/your/logo.pdf");
stampAnnotation.setAppearanceStreamGenerator(new ContentResolverAppearanceStreamGenerator(logoUri);
// Add the newly created annotation to the document.
document.getAnnotationProvider().addAnnotationToPage(stampAnnotation);

iOS

// Create `PSPDFDocument`.
let document = PSPDFDocument(url: documentURL)
// Create the URL of the appearance stream that uses a PDF file.
let samplesURL = Bundle.main.resourceURL?.appendingPathComponent("Samples")
let logoURL = samplesURL?.appendingPathComponent("PSPDFKit Logo.pdf")
// Create a new stamp annotation using the appearance stream generator.
let vectorStampAnnotation = PSPDFStampAnnotation()
// Set the appearance stream.
vectorStampAnnotation.appearanceStreamGenerator = PSPDFFileAppearanceStreamGenerator(fileURL: logoURL)
// Set the bounding box.
vectorStampAnnotation.boundingBox = CGRect(x: 180, y: 150, width: 444, height: 500)
// Add the newly created annotation to the document.
document.add([vectorStampAnnotation])
// Create `PSPDFDocument`.
PSPDFDocument *document = [[PSPDFDocument alloc] initWithURL:documentURL];
// Create the URL of the appearance stream that uses a PDF file.
NSURL *samplesURL = [NSBundle.mainBundle.resourceURL URLByAppendingPathComponent:@"Samples"];
NSURL *logoURL = [samplesURL URLByAppendingPathComponent:@"PSPDFKit Logo.pdf"];
// Create a new stamp annotation using the appearance stream generator.
PSPDFStampAnnotation *vectorStampAnnotation = [[PSPDFStampAnnotation alloc] init];
// Set the appearance stream.
vectorStampAnnotation.appearanceStreamGenerator = [[PSPDFFileAppearanceStreamGenerator alloc] initWithFileURL:logoURL];
vectorStampAnnotation.boundingBox = CGRectMake(180.f, 150.f, 444.f, 500.f);
// Set the bounding box.
CGRect boundingBox = { .origin.x = 180.f, .origin.y = 150.f, .size.height = 444.f, .size.width = 500.f };
vectorStampAnnotation.boundingBox = boundingBox;
// Add the newly created annotation to the document.
[docment addAnnotations:@[imageStampAnnotation] options:nil];

To learn more about how to programmatically create vector stamp annotations, check out our Android and iOS appearance streams guides.

Add vector stamps in the stamp picker

You can also add vector stamps in the stamp picker alongside the default stamps, or even replace Nutrient’s default set of annotations.

To learn more about customizing the stamp picker, including code samples, check out the “Custom Stamp Annotations” example in our PSPDFCatalog project, along with our stamp annotations configuration guide.

Customizing the stamp picker on Android requires Nutrient Android SDK 4.2 or higher.

FAQ

What are vector stamp annotations in a PDF?

Vector stamp annotations use scalable graphics defined by paths instead of pixels. They maintain perfect clarity at any zoom level and are ideal for logos, technical drawings, or reusable shapes.

Why should I use vector stamps instead of image-based stamps?

Vector stamps stay sharp when zoomed or printed and have smaller file sizes compared to raster image stamps. They also support transparency and look cleaner across devices.

Can I create custom vector stamps with the Nutrient SDK?

Yes. Nutrient SDKs for Android (4.1+) and iOS (7.1+) allow developers to create vector stamps using appearance stream generators with custom PDF content.

Do vector stamps work with the built-in stamp picker?

Yes. You can add custom vector stamps to the stamp picker or replace the default set entirely for a more tailored user experience.

Are vector stamps compatible with other annotation types?

They are. Appearance streams used for vector stamps can also be applied to ink, free text, and other compatible annotations.

Rad Azzouz

Rad Azzouz

Tomáš Šurín

Tomáš Šurín

Server and Services Engineer

Tomáš has a deep interest in building (and breaking) stuff both in the digital and physical world. In his spare time, you’ll find him relaxing off the grid, cooking good food, playing board games, and discussing science and philosophy.

Explore related topics

FREE TRIAL Ready to get started?