Annotate Images

While it was always possible to annotate images in PSPDFKit, doing so previously required some extra code. You had to convert the image to PDF, be sure to update the annotation tools and UI to show only relevant options, and extract the image data back when a save occurred.

In PSPDFKit 7.3 for iOS, we introduced a new class, PSPDFImageDocument, which makes this process much simpler. All you need to do is pass your image to PSPDFImageDocument and we handle the rest. We even simplified the PDF controller configuration by providing a pre-built configuration that adjusts the UI so that it works great for images. Take a look at the AnnotateImagesExample to learn more.

ℹ️ Note: This feature requires the Document Editor component.

PSPDFImageDocument is a subclass of PSPDFDocument that can be initialized with an image file. Although it has capabilities similar to its parent class, you should keep the following limitations in mind.

Image Formats

You can initialize a PSPDFImageDocument using a local image file URL. PSPDFImageDocument supports the JPEG and PNG file formats.

Annotation Types

Although you can technically use any annotation type with PSPDFImageDocument, we recommend that you disable certain annotation tools when working with image documents. For example, text selection- or text extraction-based annotations, such as highlight and underline annotations, do not make sense for a PSPDFImageDocument, because there will be no selectable text in the document.

We recommend that you initialize your PSPDFViewController with the PSPDFConfiguration.imageConfiguration preset. This will automatically disable annotation types that are not relevant for image files.

1
let controller = PSPDFViewController(document: imageDocument, configuration: PSPDFConfiguration.image)
Copy
1
PSPDFViewController *controller = [[PSPDFViewController alloc] initWithDocument:imageDocument configuration:PSPDFConfiguration.imageConfiguration];

Customize the UI

We also recommend that you only expose relevant UI elements to your users. For example, disable the document editing feature to disallow adding new pages to an image document. Here‘s a basic UI customization for a PSPDFViewController presenting a PSPDFImageDocument:

Copy
1
2
3
4
5
6
let rightItems = [controller.annotationButtonItem, controller.activityButtonItem, controller.searchButtonItem]
let leftItems = [controller.outlineButtonItem, controller.brightnessButtonItem]
controller.navigationItem.setRightBarButtonItems(rightItems, for: .document, animated: false)
controller.navigationItem.setLeftBarButtonItems(leftItems, for: .document, animated: false)

controller.navigationItem.leftItemsSupplementBackButton = true
Copy
1
2
3
4
5
6
NSArray<UIBarButtonItem *> *rightItems = @[controller.annotationButtonItem, controller.activityButtonItem, controller.searchButtonItem];
NSArray<UIBarButtonItem *> *leftItems = @[controller.outlineButtonItem, controller.brightnessButtonItem];
[controller.navigationItem setLeftBarButtonItems:rightItems forViewMode:PSPDFViewModeDocument animated:NO];
[controller.navigationItem setLeftBarButtonItems:leftItems forViewMode:PSPDFViewModeDocument animated:NO];

controller.navigationItem.leftItemsSupplementBackButton = YES;

See the AnnotateImagesExample example from PSPDFCatalog for more details.

Saving

PSPDFImageDocument will automatically update the underlying image file on every save. This will result in the annotations being rasterized and embedded into the image. If you create a new document with the same image, you will not be able to modify the embedded annotations any longer, as they will essentially just be part of the image.

You can keep the image document in memory to preserve the ability to edit added annotations. See the Annotation-Saving Mechanism and Annotation- and Bookmark-Saving Triggers guide articles for more information.

PSPDFImageDocument also supports serialization and deserialization via the [NSSecureCoding] protocol. If you need to preserve editing abilities for an image document between application launches, you can simply archive and unarchive it using the standard iOS serialization APIs.