Appearance Streams

PSPDFKit allows you to define custom appearance streams on any annotation type by setting the PSPDFAnnotation’s appearanceStreamGenerator property.

This is especially useful for stamp annotations. In this article, we’ll discuss the advantages of using a vector (appearance stream) stamp annotation over a bitmap stamp annotation.

Unlike bitmap stamp (UIImage-based) annotations, vector annotations allow transparency and high-resolution zooming.

For more on this topic, please refer to our Use Vector Stamps Instead of Blurry Shapes and What Are Appearance Streams? blogs.

Stamp Annotation with a Bitmap Image

Here’s how to programmatically add a bitmap stamp annotation:

Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Create `PSPDFDocument`.
let document = PSPDFDocument(url: documentURL)

// Create a new stamp annotation with a `UIImage`.
let imageStamp = PSPDFStampAnnotation()

// Set the appearance stream.
imageStamp.image = UIImage(named: "PSPDFKit Logo.jpg")

// Set the bounding box.
imageStamp.boundingBox = CGRect(x: 180, y: 150, width: 444, height: 500)

// Add the newly created annotation to the document.
document.add([imageStamp])
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Create `PSPDFDocument`.
PSPDFDocument *document = [[PSPDFDocument alloc] initWithURL:documentURL];

// Create a new stamp annotation with a `UIImage`.
PSPDFStampAnnotation *imageStampAnnotation = [[PSPDFStampAnnotation alloc] init];

// Set the appearance stream.
imageStampAnnotation.image = [UIImage imageNamed: @"PSPDFKit Logo.jpg"];

// Set the bounding box.
imageStampAnnotation.boundingBox = { .origin.x = 180.f, .origin.y = 150.f, .size.height = 444.f, .size.width = 500.f };

// Add the newly created annotation to the document.
[document addAnnotations:@[imageStampAnnotation] options:nil];

Stamp Annotation with an Appearance Stream

Here’s how to programmatically add a vector stamp annotation:

Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 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])
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 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.
vectorStampAnnotation.boundingBox = { .origin.x = 180.f, .origin.y = 150.f, .size.height = 444.f, .size.width = 500.f };;

// Add the newly created annotation to the document.
[document addAnnotations:@[vectorStampAnnotation] options:nil];

Take a look at AddVectorStampAnnotationProgrammaticallyExample inside the Catalog app, as it shows how to create vector stamp annotations programmatically.

You can also refer to the Default Stamp Annotations section of the Stamp Annotations Configuration guide, which illustrates how to customize the default stamp annotations available in the stamp picker dialog.