Ruby just got a real sepia filter

January 6, 2026

Why ruby-libgd is becoming Ruby’s new graphics engine

Yesterday something important happened in the Ruby ecosystem.

I added a native sepia filter to ruby-libgd — Ruby’s new binding to the GD Graphics Library — and with it Ruby took another step toward regaining something it quietly lost over the last decade: a true raster graphics engine.

This was not a Ruby wrapper calling out to ImageMagick. This was not a shell command.

This was pixel-level image processing running directly inside Ruby.

And that changes everything.


Advertise on RubyStackNews

RubyStackNews is a niche publication read by Ruby and Rails developers worldwide. Our audience includes senior engineers, tech leads, and decision-makers from the US, Europe, and Asia.

Sponsorship Options

📝 Article Sponsorship
Your brand featured inside a technical article (clearly marked as sponsored).
📌 Inline Sponsored Block
Highlighted sponsor section embedded within an article.
📎 Sidebar Sponsor
Logo + link displayed site-wide in the sidebar.
  • Highly targeted Ruby / Rails audience
  • Organic traffic from search and developer communities
  • No ad networks — direct sponsorships only

Interested in sponsoring RubyStackNews?

Contact via WhatsApp

Why sepia is not “just a filter”

To most people, sepia looks like a nostalgic Instagram effect. To a graphics engine, sepia is something very different:

It is a full color-space transformation.

To apply sepia correctly, an engine must:

  1. Read every pixel
  2. Convert RGB to grayscale
  3. Apply weighted color remapping
  4. Write the new pixel values back into the raster

That is the same pipeline required for:

  • Satellite imagery
  • Map tile styling
  • Medical imaging
  • Scientific visualization
  • Data heatmaps

In other words:

If sepia works, the pixel engine works.

By adding sepia to ruby-libgd, I validated that Ruby now has a real image-processing core again.

Article content

The problem Ruby has had for years

For a long time, Ruby developers had to rely on:

  • ImageMagick
  • MiniMagick
  • shelling out to external binaries

These tools are powerful, but they are:

  • slow
  • fragile in production
  • memory-hungry
  • unsafe when handling untrusted images

They turn a simple task like rendering a chart or generating a map tile into a process orchestration problem.

That is not how serious backend systems should handle graphics.

What Ruby was missing was exactly what PHP, Perl and many server platforms still have:

a small, fast, embeddable raster engine.

That is what libgd provides.

And that is what ruby-libgd exposes to Ruby.


What ruby-libgd actually is

ruby-libgd is a native Ruby binding to the GD Graphics Library, written in C and designed for server-side image rendering.

It gives Ruby direct access to:

  • pixel buffers
  • drawing primitives
  • color models
  • filters
  • image encoders

No external processes. No shelling out. No fragile pipelines.

Just Ruby calling into a real raster engine.


The sepia filter in action

To test the new filter, I used a real photograph: a bowl of oranges under natural light, with glass, shadows, highlights, and texture.

This is not a synthetic test image. It is the kind of photo that exposes whether a raster engine actually works.

Applying:

image.filter(:sepia)

runs entirely inside libgd, transforming the actual pixel data.

The result preserves:

  • brightness
  • depth
  • texture
  • highlight detail

Which is exactly what you need for:

  • charts
  • reports
  • dashboards
  • maps
  • scientific images

See it live

The project already has a full visual gallery showing what Ruby can render now:

🔗 Live demo & examples https://ggerman.github.io/ruby-libgd/

You can browse:

  • charts
  • plots
  • photos
  • maps
  • dashboards

All rendered natively by Ruby.

The source code is here:

🔗 GitHub https://github.com/ggerman/ruby-libgd

And the gem is available on RubyGems:

🔗 RubyGems https://rubygems.org/gems/ruby-libgd


Why this matters beyond filters

Sepia is not the goal.

It is the proof.

Once you can reliably:

  • read pixels
  • transform colors
  • write them back
  • and encode the result

You unlock:

  • GIS map tile pipelines
  • scientific visualization
  • PDF report rendering
  • data dashboards
  • image processing at scale

This is the foundation Ruby needs to compete in:

  • geospatial systems
  • data platforms
  • reporting infrastructure
  • scientific tooling
Article content

The bigger picture

At RubyConf 2025, it was openly acknowledged that Ruby struggles with:

  • map tile generation
  • image rendering
  • graphics pipelines

ruby-libgd exists because of that gap.

The sepia filter added yesterday is one more brick in rebuilding Ruby’s graphics stack — not as a wrapper, but as a real engine.

Ruby can create images again.

And now it can color them properly too.

Article content

Leave a comment