Skip to main content

color-counter

A command-line tool to count and analyze colors in PDF files. It rasterizes each page, extracts pixel color frequencies, and displays ranked color tables with terminal swatches.

Features

  • Per-page color tables and a cross-page summary
  • Three quantization methods to group similar colors: exact top-N, k-means (RGB), k-means (perceptual LAB)
  • Optional gray separation: isolate near-gray colors into their own table
  • Page range selection
  • Pixel-sampling stride for faster analysis of large documents
  • Configurable terminal color system for accurate swatch rendering

Installation

Requires Python 3.10+.

pip install -e .

For development (includes pytest):

pip install -e ".[dev]"

The lab quantization method additionally requires scikit-image:

pip install scikit-image

Usage

color-counter file.pdf

By default, only the global summary is printed. Add --per-page to also print a table for every page.

Examples

# Summary only (default)
color-counter report.pdf

# Per-page tables + summary
color-counter report.pdf --per-page

# Analyze only pages 2 to 5
color-counter report.pdf --pages 2-5

# Reduce to 8 dominant colors using perceptual clustering
color-counter report.pdf --reduce 8 --method lab

# Separate gray shades (max channel spread ≤ 15) into their own table
color-counter report.pdf --gray-threshold 15

# Fix swatches that all look the same color
color-counter report.pdf --color-system truecolor

# Fast pass on a large document (sample every 4th pixel)
color-counter report.pdf --sample-step 4

Options

Option Default Description
--dpi N 150 Rasterization resolution
--top N 10 Top N colors shown per table
--reduce N — Reduce palette to N colors before reporting
--method kmeans Color reduction method: exact, kmeans, lab
--sample-step N 1 Pixel sampling stride (>1 skips pixels for speed)
--pages RANGE all Page range, e.g. 1-3 or 2,4
--summary / --no-summary on Print aggregated total across all pages
--per-page / --no-per-page off Print a color table for each page
--gray-threshold N — Separate colors with max RGB spread ≤ N into a gray table
--color-system auto Terminal color depth: auto, truecolor, 256, standard, none

Color reduction methods

Method Description
exact Keep the N most frequent raw colors, no merging
kmeans Cluster similar colors in RGB space (weighted by pixel count)
lab Cluster in perceptual CIE LAB space — better at grouping visually similar colors. Requires scikit-image.

Gray threshold

A color is classified as gray when its maximum RGB channel minus its minimum RGB channel is at or below the threshold.

  • 0 — only exact grays where R = G = B (pure black, white, neutral)
  • 15 — also catches near-grays from anti-aliasing or compression artifacts

Swatch colors look wrong

If swatches all appear as the same color, your terminal's color depth is being misdetected. Run with --color-system truecolor to force 24-bit color output.

Architecture

Module Role
rasterizer.py PDF → PIL Images via PyMuPDF
analyzer.py PIL Image → ColorData (unique colors + pixel counts)
quantizer.py ColorData → reduced ColorData (exact / k-means / LAB)
reporter.py ColorData → Rich terminal tables
cli.py Click entry point wiring everything together

License

MIT — see LICENSE.

Metadata

Release files for color-counter 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for color-counter 0.1.0
File Size Uploaded Provenance
color_counter-0.1.0.tar.gz 11.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for color-counter 0.1.0
File Interpreter ABI Platform
color_counter-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 23.9 kB

Release files / color_counter-0.1.0.tar.gz

Download URL color_counter-0.1.0.tar.gz
Size 11.1 kB
Tags Source
SHA-256 checksum
How to use checksums
00848bdbf6d7ae795004abf0715965d73755e6de21a0932995bf5721e8a05ecf
BLAKE2b-256 checksum
How to use checksums
809fbcf3c812c94e5c0724e632fc34d25860937ef070891a13920d8dc60fcb02
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.2.1 CPython/3.10.12 Linux/6.8.0-124-generic

Release files / color_counter-0.1.0-py3-none-any.whl

Download URL color_counter-0.1.0-py3-none-any.whl
Size 12.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ff482b7bad38d14d423d06a24a5c73804d2d420670bfd467a0610c3c8f330551
BLAKE2b-256 checksum
How to use checksums
43f503a0b05271df6b869cc6951bf3a45796c2859bd7a4a1ff953130131b0152
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.2.1 CPython/3.10.12 Linux/6.8.0-124-generic

Security for color-counter 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page