Skip to content

DPI / PPI Calculator — Java source

Compute screen pixel density (PPI/DPI), dot pitch, physical dimensions, and aspect ratio from any resolution. Solve for PPI from a diagonal, or derive the diagonal from a known PPI - all in your browser.

This is the Java implementation — the same logic the interactive tool runs, in a shareable, citable form.

// =============================================================================
//  DpiPpi.java — CosmoDev polyglot showcase port of the `dpi-ppi` tool
//  -----------------------------------------------------------------------------
//  Language : Java (Java 17, standard library only)
//  Source:   ported from src/lib/dpi-ppi.ts (the canonical, live TypeScript
//             lib); mirrors src/tool-sources/dpi-ppi/{python.py,rust.rs}
//  License  : display source — part of CosmoDev's polyglot tool pages
//             (dev.cosmolabs.org). Shown verbatim alongside the JS/TS/Go/Rust/
//             Python ports and the other language ports.
//  -----------------------------------------------------------------------------
//  Display pixel-density math. Diagonal length in pixels, pixels-per-inch
//  computed from a known physical diagonal, physical width/height/diagonal in
//  both inches and millimeters, dot pitch in millimeters per pixel, and a
//  reduced aspect ratio — all derived from a pixel resolution.
//
//  Pure, deterministic, side-effect free. A zero divisor does not throw:
//  double division follows IEEE-754, so x / 0.0 yields ±Infinity and
//  0.0 / 0.0 yields NaN — callers should guard with Double.isFinite before
//  display. (The Python port routes every division through a safeDiv wrapper
//  only because Python raises ZeroDivisionError for float division.)
// =============================================================================

package com.cosmolabs.cosmodev;

/** Display pixel-density math. */
public final class DpiPpi {
    private DpiPpi() {}

    /** Fixed conversion factor between inches and millimeters. */
    private static final double MM_PER_INCH = 25.4;

    /** Pixels-per-inch result. */
    public record Ppi(double ppi) {}

    /** Physical dimensions of a display, in inches and millimeters. */
    public record PhysicalSize(
            double widthIn,
            double heightIn,
            double diagonalIn,
            double widthMm,
            double heightMm) {}

    /**
     * Diagonal length in pixels: √(w² + h²).
     * The sign of the inputs is irrelevant because both terms are squared.
     */
    public static double diagonalPixels(double w, double h) {
        return Math.sqrt(w * w + h * h);
    }

    /** Pixels per inch, given a resolution and a known physical diagonal in inches. */
    public static Ppi computePpi(double w, double h, double diagonalInches) {
        return new Ppi(diagonalPixels(w, h) / diagonalInches);
    }

    /**
     * Derive inches and millimeters from a resolution and a ppi. The diagonal
     * is recomputed from the derived inch dimensions so it stays consistent
     * with the width/height values.
     */
    public static PhysicalSize physicalSize(double w, double h, double ppi) {
        double widthIn = w / ppi;
        double heightIn = h / ppi;
        return new PhysicalSize(
                widthIn,
                heightIn,
                diagonalPixels(widthIn, heightIn),
                widthIn * MM_PER_INCH,
                heightIn * MM_PER_INCH);
    }

    /** Dot pitch (pixel size) in millimeters per pixel: 25.4 / ppi. */
    public static double dotPitch(double ppi) {
        return MM_PER_INCH / ppi;
    }

    /**
     * Integer greatest-common-divisor via Euclid's algorithm, used to reduce
     * aspect ratios. Inputs are truncated toward zero (the (long) cast) and
     * taken in absolute value first, so the sign and fractional part of the
     * inputs never matter.
     */
    private static long gcd(double a, double b) {
        long x = Math.abs((long) a);
        long y = Math.abs((long) b);
        while (y != 0) {
            long t = y;
            y = x % y;
            x = t;
        }
        return x;
    }

    /**
     * Reduced aspect ratio as "w:h" (e.g. "16:9"). Returns "-" when either
     * side is not a positive number (this also covers NaN, since every
     * comparison with NaN is false).
     */
    public static String aspectRatio(double w, double h) {
        if (!(w > 0) || !(h > 0)) {
            return "-";
        }
        long g = gcd(w, h);
        if (g == 0) {
            return "-";
        }
        long wi = (long) w;
        long hi = (long) h;
        return (wi / g) + ":" + (hi / g);
    }
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →