PdfCompare

repository·master·Indexed 42 days ago

https://github.com/red6/pdfcompare

A Java library for comparing two PDF files by rendering them and performing a pixel-by-pixel comparison. It can be used as an embedded library, via a command-line interface (CLI), or through an interactive UI to detect visual differences and define excluded areas.

Tokens
2.1K
Snippets
11
Records
11
Agent score
53%

What's inside PdfCompare

  1. Manage memory with Overflow CompareResult implementations

    master

    Comparing large PDFs can consume significant memory because images are held in RAM. To prevent OutOfMemoryError, use specialized CompareResult implementations that swap pages to disk.

    Available Implementations

    • CompareResultWithPageOverflow: Swaps every 10 pages (default) into a partial PDF and merges them at the end. This is a good balance of performance and memory.
    • CompareResultWithMemoryOverflow: Swaps pages to disk when the JVM heap reaches a critical threshold (default is 70% of max heap).

    Usage:

    new PdfComparator("expected.pdf", "actual.pdf", new CompareResultWithPageOverflow()).compare();

    Advanced Memory Tuning (via application.conf)

    If using the overflow implementations, you can tune these settings in an application.conf file:

    • imageCacheSizeCount: Number of images cached by PdfBox.
    • maxImageSizeInCache: Max size of an image to be cached.
    • mergeCacheSizeMB: Memory cache for the merge process.
    • swapCacheSizeMB: Memory cache for partial writes.
    • documentCacheSizeMB: Cache for loaded documents.
    • overallTimeoutInMinutes: Safety timeout to detect deadlocks.
    • executorTimeoutInSeconds: Timeout for executors after overall timeout is reached.
  2. Define Exclusions (Ignored Areas)

    master

    You can define rectangular areas to ignore during comparison using either a configuration file or the programmatic API.

    Using an Exclusion File

    Create a file in HOCON/JSON format. Entries without units are treated as pixels (default rendering is 300DPI). Units like mm, cm, or pt (1/72 inch) are supported.

    Exclusion File Format:

    exclusions: [
        {
            page: 2
            x1: 300
            y1: 1000
            x2: 550
            y2: 1300
        },
        {
            // page is optional; if omitted, applies to all pages
            x1: 130.5mm
            y1: 3.3cm
            x2: 190mm
            y2: 3.7cm
        },
        {
            page: 7
            // coordinates are optional; if omitted, the whole page is excluded
        }
    ]

    Apply the file via the API:

    new PdfComparator("expected.pdf", "actual.pdf").withIgnore("ignore.conf").compare();

    Using the Programmatic API

    Add exclusions directly in your code using PageArea objects:

    new PdfComparator("expected.pdf", "actual.pdf")
        .withIgnore(new PageArea(1, 230, 350, 450, 420))
        .withIgnore(new PageArea(2))
        .compare();
  3. Use PdfCompare via CLI or UI

    master

    PdfCompare provides two ways to run without writing code:

    1. Interactive UI: Run the JAR file without arguments to start an interactive UI. This allows you to select files and visually mark areas to ignore (which are saved to an ignore-file).
    2. Command Line: Provide the expected and actual files as arguments.

    CLI Usage:

    java -jar pdfcompare-x.x.x-full.jar [EXPECTED] [ACTUAL]

    Use -h or --help for help text.

  4. Install PdfCompare via Maven

    master

    To use PdfCompare in your Java project, add it as a dependency in your pom.xml. Check Maven Central for the most current version.

    <dependencies>
      <dependency>
        <groupId>de.redsix</groupId>
        <artifactId>pdfcompare</artifactId>
        <version>...</version> <!-- see current version in the maven central tag above -->
      </dependency>
    </dependencies>
  5. Handle Encrypted PDF files

    master

    If the PDFs are password protected, provide the passwords using withExpectedPassword or withActualPassword:

    new PdfComparator("expected.pdf", "actual.pdf")
        .withExpectedPassword("somePwd")
        .withActualPassword("anotherPwd")
        .compare();
  6. Configure PdfCompare via API

    master

    You can override settings programmatically using withEnvironment and a SimpleEnvironment. SimpleEnvironment delegates unassigned settings to the default environment.

    new PdfComparator("expected.pdf", "actual.pdf")
        .withEnvironment(new SimpleEnvironment()
            .setActualColor(Color.green)
            .setExpectedColor(Color.blue))
        .compare();

    Available Configuration Options

    OptionDefaultDescription
    DPI300Rendering DPI
    expectedColor00B400 (GREEN)HTML-style hex color (no #) for expected-only pixels
    actualColorD20000 (RED)HTML-style hex color (no #) for actual-only pixels
    tempDirjava.io.tmpdirDirectory for temporary files
    allowedDifferenceInPercentPerPage0.2% of pixels allowed to differ per page before reporting a difference
    parallelProcessingtrueWhether to use parallel processing
    addEqualPagesToResulttrueIf false, only pages with differences are included in the output PDF
    failOnMissingIgnoreFilefalseIf true, throws exception if ignore file is missing
  7. Use PdfCompare as a Java library

    master

    The primary way to use PdfCompare is as an embedded library. It renders PDF pages to bitmaps and performs a pixel-by-pixel comparison.

    Basic Comparison and Output:

    // Compares files and writes a diff PDF to 'diffOutput'
    new PdfComparator("expected.pdf", "actual.pdf").compare().writeTo("diffOutput");

    Querying Results: Use the CompareResult object returned by .compare() to inspect the outcome:

    final CompareResult result = new PdfComparator("expected.pdf", "actual.pdf").compare();
    if (result.isNotEqual()) {
        System.out.println("Differences found!");
    }
    if (result.isEqual()) {
        System.out.println("No Differences found!");
    }
    if (result.hasDifferenceInExclusion()) {
        System.out.println("Differences in excluded areas found!");
    }
    // Returns page areas where differences were found
    result.getDifferences();

    Note on Input Types: The compare method accepts filenames as String, File, Path, or InputStream.

    new PdfComparator("expected.pdf", "actual.pdf").compare().writeTo("diffOutput");
  8. PdfCompare CLI Options

    master

    The following options are available when running the PdfCompare CLI. Options can be provided using short flags or long flags (e.g., -o or --output).

    ShortLongArgumentDescription
    -h--help(none)Displays this text and exit
    -o--outputoutputProvide an optional output file for the result
    -x--exclusionsexclusionsProvide an optional file with exclusions
    --exppwd--expected-passwordexpected-passwordProvide a password for the expected file
    --actpwd--actual-passwordactual-passwordProvide a password for the actual file
    java -jar pdfcompare-x.x.x-full.jar [EXPECTED] [ACTUAL] -o result.txt -x exclusions.txt
  9. Run PdfCompare via Command Line

    master

    PdfCompare can be executed from the command line by passing arguments to the Main class. If arguments are provided, the application runs in CLI mode and executes the command specified by the arguments. If no arguments are provided, the application defaults to starting its interactive User Interface (UI).

    java -cp <classpath> de.redsix.pdfcompare.Main [cli-arguments]