Skip to main content

pkgprint

Print and packaging math — straight to your Python project.

PyPI version Python 3.8+ License: MIT Tests

pkgprint is a Python library for the fiddly arithmetic behind print and packaging production: unit conversions, colour model translations, standard paper and box sizes, bleed calculations, print-readiness file checking, WCAG colour contrast validation, and box dieline layout. It's built for developers who work with print pipelines, packaging design tools, or any application that touches commercial print — people who need correct, well-tested answers, not approximations. The core math is zero-dependency; Pillow is only pulled in when you actually check image files.


Installation

pip install pkgprint

Quick Start

import pkgprint

# Look up a standard size and convert to inches
w, h = pkgprint.paper_size("A4")                    # (210, 297)
pkgprint.mm_to_inches(w)                            # 8.267716535433072

# Add 3 mm bleed to a US business card
pkgprint.add_bleed(89, 51)                          # (95, 57)

# Translate a brand colour between colour models
pkgprint.cmyk_to_rgb(0, 100, 100, 0)               # (255, 0, 0)
pkgprint.rgb_to_hex(255, 0, 0)                      # '#FF0000'

# Check text contrast against WCAG AA
pkgprint.contrast_ratio((0, 0, 0), (255, 255, 255)) # 21.0
result = pkgprint.check_wcag_compliance((140, 140, 140), (255, 255, 255))
result.passed                                        # False  (3.36:1 < 4.5)

# Calculate flat sheet size for a shipping box (RSC style)
pkgprint.rsc_flat_size(300, 200, 150)               # (1035.0, 350)

Why pkgprint?

  • Zero-dependency core. Unit conversions, colour math, paper sizes, bleed calculations — none of it needs an external package. Pillow is only imported when you call check_dpi, check_color_mode, or check_dimensions.
  • Formulas from the field. The WCAG relative luminance uses the exact sRGB gamma correction; RSC flat-size formulas match industry practice; paper sizes reference ISO 216 and ANSI standards. Shortcuts are flagged explicitly in docstrings.
  • Rigorous tests. 220+ tests covering normal cases, edge cases, and error paths. The suite caught a real production edge case during development: 2480 × 3508 px — the widely-cited "A4 at 300 DPI" pixel count — actually resolves to 299.97 DPI due to mm→inch rounding, and fails a 300 DPI check. pkgprint ships the correct 2481 px threshold.
  • MIT licensed, commercially free. Use it in client projects, SaaS products, or internal tooling without restriction.

Feature Overview

Module Description Functions
units mm ↔ inches ↔ points, DPI ↔ PPI conversions 6
color CMYK ↔ RGB ↔ hex colour model conversions 4
paper Standard paper sizes (ISO, ANSI, US) and common box dimensions 3
print_specs Bleed, safe margin, and trim size calculations 3
check Image file print-readiness: DPI, colour mode, and dimension checks 4 + 2 types
accessibility WCAG 2.1 contrast ratio checking and colour adjustment 4 + 1 type
dieline Flat sheet and named panel layout for RSC and Mailer box styles 3 + 1 type

Module Reference

📏 units — Measurement Conversions

Converts between the measurement units used throughout print and design workflows. DPI and PPI functions are semantic aliases — numerically identical, provided for clarity in code that mixes screen and print contexts.

Function Converts
mm_to_inches(mm) millimetres → inches
inches_to_mm(inches) inches → millimetres
mm_to_points(mm) millimetres → PostScript points (1 pt = 1/72 in)
points_to_mm(points) PostScript points → millimetres
dpi_to_ppi(dpi) DPI → PPI (identity, semantic alias)
ppi_to_dpi(ppi) PPI → DPI (identity, semantic alias)
import pkgprint

pkgprint.mm_to_inches(25.4)     # 1.0
pkgprint.mm_to_inches(210)      # 8.267716535433072  (A4 width)
pkgprint.inches_to_mm(1)        # 25.4
pkgprint.mm_to_points(25.4)     # 72.0  (1 inch = 72 pt)

🎨 color — Colour Model Conversions

Converts between the colour models used in print (CMYK) and screen/web (RGB, hex) workflows. CMYK channels use the 0–100 scale (percentage); RGB channels use 0–255.

Function Converts
cmyk_to_rgb(c, m, y, k) CMYK (0–100 each) → RGB (0–255 each)
rgb_to_cmyk(r, g, b) RGB (0–255 each) → CMYK (0–100 each)
hex_to_rgb(hex_str) Hex colour string → RGB tuple
rgb_to_hex(r, g, b) RGB tuple → hex colour string
import pkgprint

pkgprint.cmyk_to_rgb(0, 100, 100, 0)    # (255, 0, 0)   — pure red
pkgprint.cmyk_to_rgb(0, 0, 0, 100)      # (0, 0, 0)     — process black
pkgprint.rgb_to_cmyk(255, 0, 0)         # (0.0, 100.0, 100.0, 0.0)
pkgprint.rgb_to_hex(255, 0, 0)          # '#FF0000'
pkgprint.hex_to_rgb('#FF0000')          # (255, 0, 0)

📄 paper — Standard Paper & Box Sizes

Looks up standard paper sizes (ISO A-series, B-series, US Letter/Legal/Tabloid, business cards) and common shipping box sizes. All dimensions are in millimetres. Lookups are case-insensitive.

Function Returns
paper_size(name) (width_mm, height_mm) for a named paper size
list_paper_sizes() Sorted list of all available paper size names
box_size(name) (length_mm, width_mm, height_mm) for a named box size
import pkgprint

pkgprint.paper_size("A4")                 # (210, 297)
pkgprint.paper_size("Letter")             # (216, 279)
pkgprint.paper_size("Business Card US")   # (89, 51)
pkgprint.paper_size("Business Card ISO")  # (85, 55)
pkgprint.box_size("RSC Medium")           # (305, 229, 152)

pkgprint.list_paper_sizes()[:4]
# ['A0', 'A1', 'A2', 'A3']

Note on business card sizes: ISO/European business cards are 85×55 mm; US business cards are 89×51 mm (3.5"×2"). Both are available under distinct names.


✂️ print_specs — Bleed, Margin & Trim Calculations

Calculates the three key dimension sets in any print-ready file: the bleed size (artwork canvas with bleed added), the safe area (the zone guaranteed not to be trimmed), and the trim size (finished size recovered from a bled-up file).

Function Purpose
add_bleed(w, h, bleed_mm=3) Add bleed to both dimensions; returns (bleed_w, bleed_h)
safe_margin(w, h, margin_mm=5) Subtract safe margin; returns (safe_w, safe_h)
trim_size(w, h, bleed_mm=3) Recover trim size from a bled-up file; returns (trim_w, trim_h)
import pkgprint

# US business card: 89×51 mm trim, 3 mm bleed → canvas size
pkgprint.add_bleed(89, 51)               # (95, 57)

# A4 with 5 mm bleed
pkgprint.add_bleed(210, 297, bleed_mm=5) # (220, 307)

# Safe text area inside A4 (5 mm margin from each edge)
pkgprint.safe_margin(210, 297)           # (200, 287)

# Recover trim size from a 95×57 mm bled-up business card
pkgprint.trim_size(95, 57)               # (89, 51)

✅ check — Print-Readiness File Checker

Inspects an actual image file and reports whether it meets commercial print requirements. Requires Pillow (installed automatically with pip install pkgprint).

Each check returns a CheckResult with .passed, .actual, .expected, and .message. full_report() collects all three checks without raising on individual failures.

Function Checks
check_dpi(path, w_mm, h_mm, min_dpi=300) Effective DPI at the target print size
check_color_mode(path, required_mode="CMYK") Colour mode (CMYK, RGB, Grayscale…)
check_dimensions(path, w_mm, h_mm, tolerance_mm=1) Physical size at native DPI vs target
full_report(path, w_mm, h_mm, min_dpi=300, required_color_mode="CMYK") All three checks combined
import pkgprint

report = pkgprint.full_report("artwork.tif", 210, 297)

print(report.summary)
# DPI check:        PASS — Effective DPI 304.8 ≥ 300 ...
# Colour mode:      FAIL — Colour mode is 'RGB' but 'CMYK' is required ...
# Dimensions check: PASS — Dimensions 210.0×297.0 mm match target ...
# Overall:          NOT PRINT-READY

report.passed          # False
report.dpi.passed      # True
report.color_mode.passed  # False
report.dimensions.actual  # (210.0, 297.0)

# Individual checks
result = pkgprint.check_dpi("artwork.tif", 210, 297, min_dpi=300)
result.passed    # True / False
result.actual    # effective DPI on the worst axis
result.message   # human-readable diagnostic

Result types: CheckResult(passed, actual, expected, message) and PrintReport(dpi, color_mode, dimensions, passed, summary).


♿ accessibility — WCAG Colour Contrast Checker

Checks foreground/background colour pairs for legibility using the WCAG 2.1 contrast formulas — useful for packaging with text, label design, or any print piece with brand colour over a background.

WCAG thresholds: AA normal text = 4.5:1, AA large text = 3.0:1, AAA normal = 7.0:1, AAA large = 4.5:1.

Function Purpose
relative_luminance(r, g, b) WCAG sRGB relative luminance (0.0–1.0)
contrast_ratio(rgb1, rgb2) WCAG contrast ratio (1.0–21.0)
check_wcag_compliance(rgb1, rgb2, level="AA", text_size="normal") Pass/fail + ratio vs WCAG threshold
suggest_darker_or_lighter(rgb_text, rgb_bg, target_ratio=4.5) Adjusted text colour that meets the target ratio
import pkgprint

# Pure black on white: maximum contrast
pkgprint.contrast_ratio((0, 0, 0), (255, 255, 255))    # 21.0

# Mid-grey on white: fails AA normal text
result = pkgprint.check_wcag_compliance((140, 140, 140), (255, 255, 255))
result.passed          # False
result.ratio           # 3.36
result.required_ratio  # 4.5
result.message         # 'Contrast ratio 3.36:1 does NOT meet WCAG AA ...'

# Get an adjusted colour that passes
adjusted = pkgprint.suggest_darker_or_lighter(
    (140, 140, 140), (255, 255, 255), target_ratio=4.5
)
adjusted                                               # (118, 118, 118)
pkgprint.contrast_ratio(adjusted, (255, 255, 255))    # 4.54

Result type: ContrastResult(passed, ratio, required_ratio, level, text_size, message).


📦 dieline — Flat Panel Layout Calculator

Calculates the flat sheet dimensions and named panel sizes for common box styles, so designers know how large their artwork canvas needs to be before structural work starts.

Planning formulas only. These are standard industry approximations. They do not account for material thickness, flute direction, or supplier-specific tuck geometry. Confirm with your structural engineer or printer's dieline template before production.

Supported styles in v0.2.0: "RSC" (Regular Slotted Container) and "Mailer" (tuck-end mailer). More styles planned — see Roadmap.

Function Returns
rsc_flat_size(length, width, height) (flat_width_mm, flat_height_mm) for an RSC box
mailer_flat_size(length, width, height) (flat_width_mm, flat_height_mm) for a tuck mailer
panel_layout(length, width, height, style="RSC") List of Panel objects with name, width_mm, height_mm
import pkgprint

# Flat canvas for a 300×200×150 mm RSC shipping box
pkgprint.rsc_flat_size(300, 200, 150)        # (1035.0, 350)
# flat_width  = 2×(300+200) + 35 mm glue flap = 1035 mm
# flat_height = 150 + 200 (top + bottom flaps each = W/2) = 350 mm

# Named panels for the same box
panels = pkgprint.panel_layout(300, 200, 150)
len(panels)       # 13  (4 body + 8 flaps + 1 glue flap)
panels[0]         # Panel(name='front', width_mm=300, height_mm=150)
panels[1]         # Panel(name='right side', width_mm=200, height_mm=150)

# Tuck mailer: 200×100×50 mm
pkgprint.mailer_flat_size(200, 100, 50)      # (635.0, 300.0)
pkgprint.panel_layout(200, 100, 50, style="Mailer")
# 7 panels: front, right side, back, left side,
#           top tuck flap, bottom tuck flap, glue flap

Result type: Panel(name, width_mm, height_mm).


Real-World Use Case

Scenario: Preparing a client's business card artwork for print.

A client uploads a logo file intended for their US business card (89×51 mm). Before sending to print, you need to verify the file meets your printer's spec, add bleed, and check that their brand colour — a warm grey — will actually be legible as text over the card's white background. With pkgprint, you look up the standard size with paper_size("Business Card US"), then run full_report() on the uploaded file: it instantly tells you the effective DPI at that print size, whether the file is CMYK or RGB (most printers require CMYK), and whether the physical dimensions match. You then call add_bleed(89, 51) to get the 95×57 mm canvas size your designer needs. Finally, check_wcag_compliance(brand_grey, (255, 255, 255)) flags that the grey is only 3.36:1 contrast — failing AA — and suggest_darker_or_lighter() proposes an adjusted value that passes, keeping the hue intact. The whole check pipeline runs in under a second, before anything goes to the print queue.


Testing & Quality

pkgprint ships with 220 tests across 7 test files, one per module. The suite covers:

  • Normal operation, edge cases (zero bleed, exact threshold values), and error paths (wrong types, out-of-range inputs, missing files)
  • Both WCAG AA and AAA thresholds for all four normal/large text combinations
  • Programmatically generated image fixtures for check.py — no binary assets committed to the repo

A note on rigor: During development, the test suite caught a subtle real-world edge case. 2480 × 3508 px is widely cited as "A4 at 300 DPI", but 2480 ÷ (210 mm / 25.4) = 299.97 DPI — fractionally below 300 due to mm→inch conversion. The correct pixel count is 2481 × 3508. The test suite uses the accurate value and the check_dpi function enforces the correct threshold.


Roadmap

  • SVG dieline output — generate production-ready flat dieline artwork directly from panel_layout() (v0.3.0)
  • Extended box styles — crash-lock bottom, auto-bottom, five-panel wrap, and more
  • Expanded paper standards — JIS B-series, Japanese Shiroku-ban, additional envelope sizes
  • CLI toolpkgprint check artwork.tif --size A4 --dpi 300 for quick pre-flight from the terminal

Contributing

Bug reports, feature requests, and pull requests are welcome at github.com/Rishabh55122/pkgprint/issues. Please open an issue before starting significant work so we can align on approach.


License

MIT — see LICENSE. Free to use in commercial and open-source projects.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pkgprint-0.2.1.tar.gz (37.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pkgprint-0.2.1-py3-none-any.whl (27.0 kB view details)

Uploaded Python 3

File details

Details for the file pkgprint-0.2.1.tar.gz.

File metadata

  • Download URL: pkgprint-0.2.1.tar.gz
  • Upload date:
  • Size: 37.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.6

File hashes

Hashes for pkgprint-0.2.1.tar.gz
Algorithm Hash digest
SHA256 bbd969caa34bf472958f9813f40cff97824047f39493c0f2be3d2c2b530d84f9
MD5 f3b32c89cb234a81e2b710cd8211d148
BLAKE2b-256 fa42bd94bae56bb8cc344512579547c8e9253d9c170341bdf828556b572c0dad

See more details on using hashes here.

File details

Details for the file pkgprint-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: pkgprint-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 27.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.6

File hashes

Hashes for pkgprint-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e5f086c0ef34dc88ad1efc4d7c4d53015eaadccc0e0b48c5c96a2805df47f72a
MD5 e1c066235b13d551c2702b8f4ce3d15f
BLAKE2b-256 6c86f707972b62bb054279bbd71cb0796347cd5c5326a04ec3c13fe8818b646f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page