Ruby Can Create Images Again

January 5, 2026

How ruby-libgd brings a real raster engine back to Ruby

For many years, Ruby quietly lost something fundamental:

The ability to generate images natively, fast, and with full control.

Yes, RMagick and MiniMagick exist. But they depend on external binaries, are slow, fragile in production, and unsuitable for things like:

  • map tile generation
  • dashboards
  • reports
  • scientific plotting
  • image processing pipelines

At RubyConf 2025 this weakness was openly acknowledged: generating images and map tiles in Ruby is a real problem.

When I saw that, I could not believe it. How could a language so widely used for backends and data processing lack a modern raster engine?

So I built one.

That is how ruby-libgd was born.

ruby-libgd — Ruby’s new raster engine

Explore the source code, examples, and install the gem to start generating charts, images, and map-grade graphics with Ruby.


A pixel engine for Ruby

ruby-libgd is a modern native binding to libgd, the same C engine used by:

  • image servers
  • PHP
  • map renderers
  • graphics pipelines

It gives Ruby the ability to:

  • create images
  • draw shapes
  • blend layers
  • render text
  • apply filters

directly, without external processes.

Once the engine existed, the real work began.


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

The first challenge: thickness

Drawing a thin line is not enough. A real graphics engine must support stroke width.

Article content

Not just for lines, but for:

  • arcs
  • circles
  • ellipses
  • rectangles
  • polygons

In ruby-libgd you can now write:

img.arc(200, 200, 260, 260, 0, 270, blue, thickness: 6)

That single line enables:

  • roads
  • borders
  • outlines
  • charts
  • map features

Without stroke thickness, there is no serious rendering.


From primitives to charts

Once the raster engine was stable, I asked:

Can Ruby now draw charts?

The answer was yes — using the same model as professional renderers: composition of primitives.

Article content

A bar in a chart is not a special object. It is simply:

img.filled_rectangle(x, y, x + bar_width, HEIGHT - MARGIN, colors[i])
img.rectangle(x, y, x + bar_width, HEIGHT - MARGIN, black, thickness: 2)

First a fill. Then a stroke.

This is how Cairo, Skia, Mapnik, and GIS engines draw everything.

Using this approach, I implemented:

  • bar charts
  • horizontal charts with error bars
  • pie charts
  • stem plots
  • stacked area charts

All rendered by Ruby into pixels.


This is more than charting

When you look at these images:

  • colored bars
  • stacked areas
  • smooth curves
  • gradients
  • transparency
  • labels

You are not just seeing “charts”.

You are seeing the same building blocks used by map engines:

Article content

Maps are not magic. They are layered graphics.

ruby-libgd gives Ruby the engine to draw them.


A full examples suite

Everything is included in the repository:

examples/
├── basics/
├── charts/
├── image_processing/
└── images/

It includes:

  • thick lines and shapes
  • gradients
  • alpha blending
  • filters
  • image composition
  • and full chart generators

You can run:

ruby examples/charts/fruit_chart_with_text.rb
ruby examples/charts/world_population.rb
ruby examples/image_processing/merge_example.rb

and watch Ruby generate real images.


Why this matters

This is not just a graphics library.

This is Ruby regaining a core system capability:

Turning data into pixels.

That enables:

  • GIS tile servers
  • dashboards
  • reporting engines
  • scientific visualization
  • game engines
  • PDF rendering

For years, Ruby had no serious raster backend.

Now it does.


What comes next

On top of this engine we can build:

  • GeoJSON
  • projections
  • tile grids
  • caches
  • layers

The hardest part — the pixel engine — is done.


Final thought

When RubyConf said:

“Generating map tiles and images in Ruby is difficult”

that was true.

It is not anymore.

Ruby has its raster engine back.

Article content

Leave a comment