Add and insert images into PDFs on Android

Nutrient Android SDK allows you to add images to PDF documents as new pages using the Processor API, the Document Editor API, or Nutrient Android SDK’s prebuilt user interface. This feature lets you enhance your existing PDF files by including photos, bitmap graphics, or scanned document images, making it ideal for creating visually enriched PDFs on Android.

If you prefer to insert an image into a PDF page as an annotation, refer to the custom stamps guide.

Using the Processor API

To add image-based pages to PDF documents using the PdfProcessor API, load your document and insert a new page from an image via a PdfProcessorTask instance. The Processor API is an excellent choice for automating PDF document processing tasks in Android apps:

val document: PdfDocument = ...

// Load an image from assets into a `Bitmap` object.
val bitmap = BitmapFactory.decodeStream(assets.open("image.png"))

// Create a task with which to add an image-based page to the document.
val task = PdfProcessorTask.fromDocument(document)

// Add an image-based page to the processor task and position the bitmap in the center of the page.
task.addNewPage(
    NewPage.emptyPage(NewPage.PAGE_SIZE_A0)
        .withPageItem(PageImage(bitmap, PagePosition.CENTER))
        .build(), document.pageCount
)

// Save it to a new document.
val outputFile = File(context.getFilesDir(), "outputDocument.pdf")
val disposable = PdfProcessor.processDocumentAsync(task, outputFile).subscribe()
PdfDocument document = ...

// Load an image from assets into a `Bitmap` object.
final Bitmap bitmap = BitmapFactory.decodeStream(getAssets().open("image.png"));

// Create a task with which to add an image-based page to the document.
final PdfProcessorTask task = PdfProcessorTask.fromDocument(document);

// Add an image-based page to the processor task and position the bitmap in the center of the page.
task.addNewPage(
    NewPage.emptyPage(NewPage.PAGE_SIZE_A0)
        .withPageItem(new PageImage(bitmap, PagePosition.CENTER))
        .build(), document.getPageCount());

// Save it to a new document.
final File outputFile = new File(context.getFilesDir(), "outputDocument.pdf");
final Disposable disposable = PdfProcessor.processDocumentAsync(task, outputFile).subscribe();

Adding new pages with the Processor API is only available if you have the Document Editor component enabled in your license.

Using the Document Editor API

You can also use the Document Editor API to add image-based pages to PDFs. The Document Editor API is particularly helpful for building a versatile document editing user interface (UI) that supports page manipulation. Its robust tools simplify the process of creating a user-friendly PDF editing interface.

Similar to how it works with the Processor API, you can leverage the Document Editor API to add a new page displaying an image:

val document: PdfDocument = ...

// Use the `PdfDocumentEditorFactory` to create a `PdfDocumentEditor`.
val documentEditor = PdfDocumentEditorFactory.createForDocument(document)

// Set up the output file location.
val outputFile = File(filesDir, "outputDocument.pdf")

// Load an image from assets into a `Bitmap` object.
val bitmap = BitmapFactory.decodeStream(assets.open("image.png"))

// Create an image-based page and position the bitmap in the center of the page.
NewPage.emptyPage(NewPage.PAGE_SIZE_A0)
        .withPageItem(PageImage(bitmap, PagePosition.CENTER))
        .build()

// Add the page to the end of the document and save to the output document.
val disposable: Disposable = documentEditor.addPage(document.getPageCount(), page)
    .flatMapCompletable { documentEditor.saveDocument(context, outputFile.outputStream(), null) }
    // Use `subscribeOn` to put `saveDocument` on a background thread, as it can be slow.
    .subscribeOn(Schedulers.io())
    // Make sure the resulting document rendering goes back on the main thread.
    .observeOn(AndroidSchedulers.mainThread())
    // Display the saved document in a new activity with the following action on `subscribe`.
    .subscribe { PdfActivity.showDocument(context, Uri.fromFile(outputFile), null) }
PdfDocument document = ...

// Use the `PdfDocumentEditorFactory` to create a `PdfDocumentEditor`.
final PdfDocumentEditor documentEditor =
    PdfDocumentEditorFactory.createForDocument(document);

// Set up the output file location.
final File outputFile = new File(getFilesDir(), "outputDocument.pdf");

// Load an image from assets into a `Bitmap` object.
final Bitmap bitmap = BitmapFactory.decodeStream(getAssets().open("image.png"));

// Create an image-based page and position the bitmap in the center of the page.
final NewPage page = NewPage.emptyPage(NewPage.PAGE_SIZE_A0)
        .withPageItem(new PageImage(bitmap, PagePosition.CENTER))
        .build();

// Add the page to the end of the document and save to the output document.
final Disposable disposable = documentEditor.addPage(document.getPageCount(), page)
    .flatMapCompletable(saved -> documentEditor.saveDocument(context, new FileOutputStream(outputFile), null))
    // Use `subscribeOn` to put `saveDocument` on a background thread, as it can be slow.
    .subscribeOn(Schedulers.io())
    // Make sure the resulting document rendering goes back on the main thread.
    .observeOn(AndroidSchedulers.mainThread())
    // Display the saved document in a new activity with the following action on `subscribe`.
    .subscribe( () -> { PdfActivity.showDocument(context,
        Uri.fromFile(outputFile), null);
    });

Using the built-in UI

Nutrient Android SDK includes a prebuilt document editing UI with functionality for adding image-based pages to PDFs. For more details on using this ready-to-deploy interface, see the document editing UI overview.