Prepress-focused PDF manipulation toolkit for graphic designers and print operators.
Rustybara is the convergence of three standalone prepress CLI tools into a unified Rust library and interactive toolset, built on the same primitives those tools proved in production:
| Origin Tool | Primitive |
|---|---|
pdf-mark-removal |
Content stream filtering, CTM math |
resize_to_bleed_or_trim_pdf |
Page box geometry (MediaBox, TrimBox, BleedBox) |
pdf-2-image |
PDF rasterization and image encoding |
It ships as a library crate (rustybara), a CLI/TUI binary (rbara), and a
GPU-accelerated PDF page viewer (rbv).
- Trim print marks — Strip printer marks, slug content, and anything outside the TrimBox from PDF pages.
- Resize to bleed — Expand MediaBox (and CropBox) by a specified bleed margin to prepare files for print production.
- Export to image — Rasterize PDF pages to JPEG, PNG, WebP, or TIFF at any DPI.
- Remap CMYK colors — Substitute specific CMYK values in PDF content streams with tolerance-based matching.
- ICC color management — Feature-gated (
color) lcms2 integration for ICC profile loading and color space transforms (RGB, CMYK, Gray). - Pipeline API — Chain operations fluently:
open → trim → resize → remap → save. - Batch processing — Process entire directories of PDFs from CLI or TUI.
- Interactive TUI — App-style terminal interface for designers who prefer guided workflows over raw CLI flags. Configurable output directory.
- Prepress vocabulary — Every API surface speaks in boxes, bleeds, and DPI — not generic PDF primitives.
Add to your Cargo.toml:
[dependencies]
rustybara = "0.1"use rustybara::PdfPipeline;
fn main() -> rustybara::Result<()> {
// Trim marks, resize to 9pt bleed, save
PdfPipeline::open("input.pdf")?
.trim()?
.resize(9.0)?
.save_pdf("output.pdf")?;
Ok(())
}use rustybara::{PdfPipeline, encode::OutputFormat, raster::RenderConfig};
fn main() -> rustybara::Result<()> {
let pipeline = PdfPipeline::open("input.pdf")?;
let config = RenderConfig::prepress(); // 300 DPI
pipeline.save_page_image(0, "page_1.jpg", &OutputFormat::Jpg, &config)?;
Ok(())
}# Trim print marks
rbara trim input.pdf
# Resize to 9pt bleed
rbara resize --bleed 9.0 input.pdf
# Export pages as 300 DPI PNGs
rbara image --format png --dpi 300 input.pdf
# Remap a CMYK color (rich black → 60/40/20/100)
rbara remap-color --from 1.0 1.0 1.0 1.0 --to 0.6 0.4 0.2 1.0 input.pdfLaunch rbara with no arguments to enter the interactive terminal interface:
rbaraArrow keys navigate, Enter selects, Esc goes back. Single-letter shortcuts are
shown in the footer bar. Press ? for the full keyboard reference.
rustybara/src/
lib.rs — Public re-exports
pipeline.rs — PdfPipeline: high-level chaining API
error.rs — Unified error type
geometry/
rect.rs — Rect (position + dimensions, PDF coordinate system)
matrix.rs — Matrix (2D affine CTM transformations)
pages/
boxes.rs — PageBoxes: TrimBox, MediaBox, BleedBox, CropBox reader
stream/
filter.rs — ContentFilter: CTM-walking content stream filter
color_ops.rs — ColorRemap: CMYK→CMYK value substitution in content streams
raster/
render.rs — PageRenderer trait, CpuRenderer (pdfium-render)
config.rs — RenderConfig (DPI, annotation toggles)
encode/
save.rs — OutputFormat enum, image encoding (JPG/PNG/WebP/TIFF)
color/ (feature-gated: "color")
icc.rs — ColorSpace, IccProfile (ICC profile loading + detection)
transform.rs — ColorTransform, RenderingIntent (lcms2 bridge)
rustybara is a high-level, prepress-scoped crate. The public API speaks in
prepress vocabulary:
// Prepress operations
PdfPipeline::open(path)?
.trim()? // Remove content outside TrimBox
.resize(bleed_pts)? // Expand page boxes by bleed margin
.remap_color(from, to, tolerance)? // Substitute CMYK values
.save_pdf(path)?; // Write the result
// Rasterization
pipeline.render_page(0, &config)?; // → DynamicImage
pipeline.save_page_image(0, path, &format, &config)?; // → file
// Page inspection
let boxes = PageBoxes::read(&doc, page_id)?;
boxes.trim_or_media() // TrimBox if present, else MediaBox
boxes.bleed_rect(9.0) // Expand trim by bleed amountRendering is behind a trait for future GPU backend support:
pub trait PageRenderer {
fn render(&self, page: &PdfPage, config: &RenderConfig)
-> Result<DynamicImage>;
}
pub struct CpuRenderer; // pdfium-render — ships today
// pub struct GpuRenderer; // vello/wgpu — future work| Crate | Role |
|---|---|
lopdf 0.40 |
PDF object graph manipulation |
pdfium-render 0.9 |
PDF rasterization via PDFium |
image 0.25 |
Bitmap encoding (JPEG, PNG, WebP, TIFF) |
rayon 1.11 |
Parallel page rendering |
lcms2 6.1 |
ICC color management (optional, color feature) |
The render_page and save_page_image functions require the PDFium shared library
at runtime. Place the appropriate binary alongside your executable:
| Platform | File |
|---|---|
| Windows | pdfium.dll |
| macOS | libpdfium.dylib |
| Linux | libpdfium.so |
Pre-built binaries: pdfium-binaries
Operations that do not rasterize (trim, resize, save_pdf, page_count,
PageBoxes::read) work without PDFium.
rbara is the interactive front-end for rustybara. It provides both a
flag-based CLI for scripting and a TUI for guided workflows.
| Key | Action |
|---|---|
↑ / ↓ |
Navigate menu |
Enter |
Select / confirm |
Esc |
Back / quit |
t |
Trim print marks |
r |
Resize to bleed |
x |
Export to image |
m |
Remap colors |
p |
Preview page |
o |
Toggle overwrite mode |
/ |
Output path |
f |
Change files |
q |
Quit |
? |
Keyboard reference overlay |
The TUI follows an app-style keyboard model — arrow keys, Enter, Esc — designed for designers who have never used a terminal before. Vim-style bindings may be layered on as aliases in a future version.
File-first workflow: launch → select file or directory → commands become
available. Directories auto-glob *.pdf files.
rbv is a minimal GPU-accelerated window for PDF page preview, built on
wgpu + winit. It is spawned by rbara on demand and communicates via
command-line arguments and exit codes.
rbv <file_path> <page_index> [--dpi <n>]
Status: Not yet implemented. See the roadmap below.
| Limitation | Notes |
|---|---|
| sRGB rasterization only | CMYK→sRGB via PDFium. ICC color transforms available via color feature for stream-level operations. |
| JPEG quality not configurable | Fixed encoder quality. --quality flag planned. |
| Spot color approximation | PDFium renders spot inks as CMYK approximations. |
| No Form XObject ColorSpace pruning | Inherited limitation from content stream filtering. |
rbv requires display server |
No headless preview. Graceful error on missing GPU. |
- ICC color management (
colormodule vialcms2) — v0.1.2 - CMYK→CMYK color remapping in content streams — v0.1.2
- RGB→CMYK conversion (vector graphics + embedded images)
- Spot color detection service
-
rbvGPU-accelerated page viewer - PDF/X validation and preflight reports
- Configurable JPEG quality (
--qualityflag) -
cargo-distrelease pipeline (Linux, Windows, macOS including Apple Silicon)
cargo test --workspace- MSRV is Rust 1.85 (edition 2024). Do not raise this floor without discussion.
- The TrimBox is always the source-of-truth reference box. It is never modified by any operation.
- Public API additions require documentation and at least one integration test.
- The app-style keyboard model is the UX baseline for
rbara. Modal bindings are opt-in aliases only.
rustybara(library): LGPL-3.0-onlyrbaraandrbv(binaries): GPL-3.0-only
The LGPL license on the library allows downstream tools to link against
rustybara without copyleft obligations on their own code, while the
binaries remain fully copyleft.
Copyright (c) 2026 Addy Alvarado