Image Picker: Add Image Annotations to PDFs on iOS

PSPDFKit uses ImagePickerController, which is a subclass of UIImage​Picker​Controller, to choose an image from your device to use. The image can either be selected from your photo library or taken using the camera. ImagePickerController is currently used when adding an image annotation to a document by tapping the image annotation button in the annotation toolbar, and when adding a new page in the Document Editor by selecting the image option for the page background.

ℹ️ Note: Make sure you have configured image permissions in your app.

Image Editor

The image picker also includes an image editor, which is automatically shown after an image has been selected. The image editor lets you zoom, crop, and rotate an image, allowing you to only use a specific part of an image. Showing the image editor can be restricted to use the selected image as is. You can disable the image editor by disabling shouldShowImageEditor.

Image Editor

Image Quality

When adding an image annotation and selecting an image, you’ll be presented with options to select the image size. This can be customized by subclassing ImagePickerController and setting allowedImageQualities in its initializer, like so:

class CustomImagePickerController: ImagePickerController {
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)

        // Setting `allowedImageQualities` to `.all` to enable the quality sheet.
        allowedImageQualities = .all
    }
}
@interface CustomImagePickerController : PSPDFImagePickerController @end

@implementation CustomImagePickerController

- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil {
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {

        // Setting `allowedImageQualities` to `PSPDFImageQualityAll` to enable the quality sheet.
        self.allowedImageQualities = PSPDFImageQualityAll;
    }
    return self;
}

@end

Delegate

To get notified of image selections or when editing is finished, you can implement ImagePickerControllerDelegate and set imageDelegate. Implementing the delegate can be done by using a subclass of ImagePickerController, so that this is used for all presentations of ImagePickerController without having to set imageDelegate again:

class CustomImagePickerController: ImagePickerController, ImagePickerControllerDelegate {
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        imageDelegate = self
    }

    func imagePickerController(_ picker: ImagePickerController, didFinishWith image: UIImage, andInfo info: [String: Any]) {
        // Do something.
    }
}
@interface PSCImagePickerController : PSPDFImagePickerController <PSPDFImagePickerControllerDelegate> @end

@implementation PSCImagePickerController

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
        self.imageDelegate = self;
    }
    return self;
}

- (void)imagePickerController:(PSPDFImagePickerController *)picker didFinishWithImage:(UIImage *)image andInfo:(NSDictionary<NSString *, id> *)info {
    // Do something.
}

@end

And don’t forget to override the class with your own subclass:

let configuration = PDFConfiguration { builder in
    builder.overrideClass(ImagePickerController.self, with: CustomImagePickerController.self)
}
PSPDFConfiguration *configuration = [PSPDFConfiguration configurationWithBuilder: ^(PSPDFConfigurationBuilder *builder) {
    [builder overrideClass:PSPDFImagePickerController.class withClass:PSCImagePickerController.class];
}];

Source Type

You can specify the source type for a subclass of ImagePickerController by overriding availableImagePickerSourceTypes as follows:

class CustomImagePickerController: ImagePickerController {
    override class func availableImagePickerSourceTypes() -> [NSNumber] {
        // Only use images from the camera. Disables the use of the Photo Library.
        return [NSNumber(value: UIImagePickerController.SourceType.camera.rawValue)]
    }
}
@interface CustomImagePickerController : PSPDFImagePickerController @end

@implementation CustomImagePickerController

+ (NSArray<NSNumber *> *)availableImagePickerSourceTypes {
    // Only use images from the camera. Disables the use of the Photo Library.
    return @[@(UIImagePickerControllerSourceTypeCamera)];
}

@end

ℹ️ Note: Make sure you’ve configured image permissions in your app. Otherwise, related image picker source types will be ignored.