background

Abachrome

License: MITRubyGem VersionDownloads

Your PDF generator creates a gradient from brand red #ff0000 to brand blue for the quarterly report cover. After round-trip conversion through your Ruby color gem, that red renders as #fe0000. The difference seems trivial - until the CMO puts both versions side-by-side during brand review. “Why don’t our colors match the style guide?”

This precision loss compounds. Each color in your 10-step gradient accumulates its own rounding error. The smooth transition becomes visibly banded. Your accessible color palette generator suggests tints that don’t meet WCAG contrast ratios because the underlying math uses naive gamma 2.2 instead of the actual sRGB curve.

These aren’t edge cases - they’re why most Ruby applications avoid advanced color features entirely. Abachrome solves these problems through:

require 'abachrome'

# Parse CSS colors and convert to Oklab space
red_oklab = Abachrome::Parsers::CSS.parse('#ff0000').to_oklab
blue_oklab = Abachrome::Parsers::CSS.parse('#0000ff').to_oklab

# Blend at the exact midpoint
midpoint = red_oklab.blend(blue_oklab, 0.5)
midpoint.to_rgb.hex_string  # "#7f007f" — verified exact match to Color.js

Start using accurate color conversions today: gem install abachrome

View source code | Read API documentation

Having trouble with color accuracy in your Ruby application? Schedule a free 30-minute consultation to discuss your color management challenges. We’ll review your current implementation and recommend specific improvements - whether that’s integrating Abachrome or building custom solutions.

Technical Implementation: How Abachrome Achieves Accuracy

The Oklab Advantage

Oklab solves a fundamental problem: RGB and HSL don’t align with human vision. When you darken yellow in HSL, it turns brown - not what designers expect. Oklab maintains perceptual relationships:

# HSL manipulation breaks perceptual uniformity
yellow_hsl = Abachrome::Parsers::CSS.parse('yellow').to_hsl
darker_hsl = yellow_hsl.lighten(-0.3)  # Becomes muddy brown

# Oklab preserves the "yellowness" while darkening
yellow_oklab = Abachrome::Parsers::CSS.parse('yellow').to_oklab
darker_oklab = yellow_oklab.lighten(-0.3)  # Still reads as dark yellow

Abachrome implements Björn Ottosson’s complete Oklab specification:

Why sRGB Implementation Details Matter

The difference between gamma 2.2 and true sRGB might seem academic until you see the results:

# Common but wrong implementation (2% error per conversion)
def simplified_to_linear(value)
  value ** 2.2
end

# Abachrome's correct implementation (IEC 61966-2-1 standard)
def correct_to_linear(value)
  if value <= 0.04045
    value / 12.92  # Linear portion near black
  else
    ((value + 0.055) / 1.055) ** 2.4
  end
end

This precision prevents the color drift that makes “Save for Web” look different from your design tool. Five round-trip conversions later, that 2% error becomes visible banding.

Real-World Applications: Solving Production Color Problems

PDF Report Generation

Your quarterly reports need consistent brand colors across charts, headers, and gradients. Abachrome ensures the CEO’s PDF looks identical to the design mockup:

# Generate accessible report color scheme from brand primary
brand_blue = Abachrome::Parsers::CSS.parse('#0066cc').to_oklab
report_colors = {
  primary: brand_blue.to_rgb.hex_string,
  light: brand_blue.lighten(0.4).to_rgb.hex_string,    # #66a3e0 - for backgrounds
  dark: brand_blue.lighten(-0.3).to_rgb.hex_string,    # #004080 - for emphasis
  contrast: brand_blue.max_contrast_color.hex_string   # #ffffff - for text
}

Need help implementing consistent PDF color themes? Let’s discuss your specific requirements.

Design System Color Scales

Generate consistent tint/shade scales that maintain perceptual uniformity:

# Create 9-step scale from any brand color
def generate_scale(hex_color)
  base = Abachrome::Parsers::CSS.parse(hex_color).to_oklab
  (-4..4).map do |step|
    base.lighten(step * 0.1).to_rgb.hex_string
  end
end

scale = generate_scale('#8b5cf6')
# ["#3d1f8d", "#5333b5", "#6948dd", "#8b5cf6", "#a57ff8", "#bfa2fa", "#d9c5fc", "#f3e8fe", "#ffffff"]

WCAG Compliance Checking

Ensure your color combinations meet accessibility standards:

def check_contrast(foreground_hex, background_hex)
  fg = Abachrome::Parsers::CSS.parse(foreground_hex)
  bg = Abachrome::Parsers::CSS.parse(background_hex)
  ratio = fg.contrast_ratio(bg)
  
  {
    ratio: ratio.round(2),
    wcag_aa_normal: ratio >= 4.5,
    wcag_aa_large: ratio >= 3.0,
    wcag_aaa_normal: ratio >= 7.0
  }
end

Getting Started with Abachrome

Installation

Add to your Gemfile:

gem 'abachrome', '~> 0.2'

Or install directly:

gem install abachrome

Basic Usage

require 'abachrome'

# Parse any CSS color format
color = Abachrome::Parsers::CSS.parse('#ff6b6b')

# Convert between color spaces
oklab = color.to_oklab
oklch = color.to_oklch
rgb = oklab.to_rgb

# Manipulate colors perceptually
lighter = oklab.lighten(0.2)
desaturated = oklch.with_chroma(oklch.chroma * 0.5)

The Story Behind Abachrome

In 2022, a Fortune 500 client needed Oklab gradients in their Prawn-generated PDFs. Their brand guidelines specified exact colors, and marketing noticed when our gradients didn’t match their design tools.

We tried existing Ruby color gems:

So we built Abachrome from first principles: BigDecimal for precision, reference implementations for validation, and production-tested reliability. After solving the client’s immediate problem, we extracted and open-sourced it because accurate color conversion shouldn’t require reimplementation.

When You Need More Than a Gem

Abachrome handles color math correctly. But production color systems involve more than math:

Architecture Decisions

Integration Complexity

Performance at Scale

Ready to solve these challenges? Schedule a free 30-minute consultation to discuss your color system architecture. We’ll help you determine whether Abachrome alone meets your needs or if you require custom color infrastructure.

Contribute to Abachrome

Found an edge case? Your bug report helps everyone using Ruby for color management.

Report Issues

Open a GitHub issue with:

Submit Improvements

  1. Fork the repository
  2. Add tests demonstrating the fix
  3. Ensure all tests pass with rake test
  4. Submit PR with clear description

We review PRs within 48 hours and provide specific feedback.

Take Action on Color Accuracy

You have three paths forward:

  1. DIY Implementation: Install Abachrome (gem install abachrome) and follow our documentation. The test suite provides examples for every use case.

  2. Guided Integration: Book a 30-minute consultation for help integrating Abachrome into your specific application. We’ll review your color requirements and provide an implementation plan.

  3. Full Color System Design: For applications where color accuracy is mission-critical, we design and implement complete color management systems. From PDF generation to accessible theming, we ensure your colors work correctly everywhere.

Don’t let inaccurate colors undermine your application’s professionalism. Whether you’re generating PDFs, building design tools, or creating accessible interfaces, correct color management matters.

Start now: Install Abachrome and run your first accurate color conversion in minutes. When you need expert guidance, we’re here to help.


Built with the same attention to detail your applications deserve. Because when your client compares the PDF to their brand guidelines, the colors should match exactly.