- Added support for additional image filters from libgd.
- Implemented convolution-based filters:
sobelsharpenlaplacianbox_blurgaussian_kernelemboss2
- Added support for advanced filters:
colorizescatter_colorscatter_ex
- Added convolution filter support using
gdImageConvolution.
Added new example scripts demonstrating filter usage:
box_blur.rbcolorize_rgb_deltas.rbcolorize_alpha_deltas.rbconvolve.rbemboss2.rbgaussian_kernel.rblaplacian.rbsobel.rbsharpen.rbscatter_color.rbscatter_ex_01.rbscatter_ex_02.rb
Example images used by the scripts are included in examples/images.
- Expanded
GD::Image#filtercoverage to include more libgd filters. - Improved filter examples and documentation.
This release expands ruby-libgd filter support and adds several
examples demonstrating convolution filters, color manipulation,
and scatter effects.
- Added
:convolvefilter support viagdImageConvolution. - Enables custom 3x3 convolution kernels directly from Ruby.
- Supports optional
divisorandoffsetparameters. - Allows implementation of advanced filters such as blur, sharpen, edge detection, emboss, and custom effects.
- Convolution operates on truecolor images.
- Raises
ArgumentErrorif kernel is not a valid 3x3 matrix. - Raises
RuntimeErrorif underlyinggdImageConvolutionfails.
kernel = [
[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]
]
img.filter(:convolve, kernel, 1.0, 0.0)- Verified compatibility with Ruby 4.0.1
- Native extension compiles successfully on Ruby 4
- Test suite passes on Ruby 4.0.1
- When building native extensions in Docker with Ruby 4.0.x,
the Ruby Docker image may require setting
RUBYARCHHDRDIRexplicitly due to a Ruby 4 header path configuration issue. - This does not affect runtime usage once the extension is built.
- No API changes
- No behavior changes
All notable changes to this project will be documented in this file.
This project follows semantic versioning.
This release significantly expands ruby-libgd’s text rendering capabilities while preserving full backward compatibility with the existing .text API.
GD::Image#text_bbox
Adds support for measuring rendered text using FreeType.
Returns the exact pixel width and height of a string for layout, centering, and label placement.
w, h = img.text_bbox("Tokyo", font: "NotoSans.ttf", size: 32)
GD::Image#text_ft
Introduces a high-quality FreeType rendering path via gdImageStringFTEx, enabling:
- DPI-aware rendering
- Multiline text
- Line spacing control
- Subpixel hinting
- Rotation support
img.text_ft(
"Tokyo\nShinjuku",
x: 100,
y: 200,
font: "NotoSans.ttf",
size: 28,
dpi: 144,
line_spacing: 1.4
)
Text measurement and layout
- Text bounding boxes now use the same FreeType engine as rendering, ensuring perfect consistency between measurement and output.
- Rotation-aware bounding boxes are supported for proper placement of angled labels.
Foundation for GIS labels, UI, and layout engines
- These new primitives enable:
- Centered and aligned labels
- Background boxes
- Collision detection
- Map overlays
- Hi-DPI text for printing and export
- The existing
GD::Image#textmethod remains unchanged and fully backward-compatible. - All new functionality is additive and does not alter existing behavior.
- Added deterministic FreeType-based specs using a bundled font fixture.
- Ensures stable, cross-platform rendering and layout measurements in CI.
This release introduces a major upgrade to ruby-libgd’s rendering engine, focused on truecolor alpha blending and antialiasing. It marks the transition from basic raster output to modern, high-quality graphics suitable for GIS, charts, and layered visualizations.
- Truecolor alpha support
- Colors now accept
[r, g, b, a]witha = 0..255 - Correct conversion to GD’s internal alpha range
- Proper blending of overlapping shapes, text, and layers
- Colors now accept
- Antialiasing for all drawing primitives
- New
GD::Image#antialias=API - Smooth edges for:
- lines
- polygons
- ellipses and circles
- filled shapes
- text
- Enables professional-grade rendering quality
- New
- Unified color pipeline
GD::Color.rgbandGD::Color.rgba- Consistent Ruby-level color representation
- Automatic conversion to GD truecolor or palette formats
- Clean curved edges and diagonals
- Correct alpha compositing between layers
- No more jagged borders when drawing with transparency
- Significantly improved visual quality for maps and diagrams
img.antialias = true
GD::Color.rgb(r, g, b)
GD::Color.rgba(r, g, b, a)
This release provides the rendering foundation required by libgd-gis:
- smooth rivers and roads
- readable labels
- layered map styling
- modern GIS-grade output
- Alpha values are expressed in Ruby as
0..255 - Internally converted to GD’s
0..127range - Existing RGB color code remains fully compatible
Added
RGBA color support via GD::Color.rgba(r, g, b, a) for all drawing operations.
True alpha blending for:
Lines
Shapes
Text rendered via FreeType (gdImageStringFT)
Images now preserve the alpha channel when saved, enabling transparent overlays.
Improved
Internal color conversion now maps Ruby RGBA (0–255) to GD’s alpha scale (0–127) correctly.
Both truecolor and palette images support transparency using gdImageColorAllocateAlpha.
Rendering output now supports layered graphics, allowing semi-transparent primitives to blend correctly.
Fixed
Drawing methods (line, text, etc.) no longer reject RGBA colors.
Alpha values are no longer misinterpreted as fully transparent due to scale mismatch.
Text rendering now respects alpha values instead of being forced opaque.
Why this matters
This release upgrades ruby-libGD from basic raster drawing to a modern compositing engine. It enables real-world use cases such as:
Transparent overlays
Heatmaps
GIS layers
Labeling over basemaps
Data visualization pipelines
This is a foundational step toward using ruby-libGD for map rendering, dashboards, and scientific graphics.
-
High-quality image scaling via
copy_resize- New
GD::Image#copy_resizemethod for resizing and copying image regions. - Supports both:
gdImageCopyResized(fast, nearest-neighbor)gdImageCopyResampled(high-quality resampling)
dst.copy_resize( src, dst_x, dst_y, src_x, src_y, src_w, src_h, dst_w, dst_h, true # enable high-quality resampling )
- New
Release date: 2026-01-05
This release introduces native sepia rendering and continues the expansion of ruby-libgd into a full image processing and raster graphics engine.
Native sepia filter
- Added
image.filter(:sepia)— a true pixel-level sepia transformation - Implemented in C using a color-matrix transform (no ImageMagick, no external tools)
- Produces consistent photographic-grade sepia tones
New example
- Added a runnable example demonstrating:
- loading an image
- applying sepia
- saving the transformed result
This example serves as both documentation and a regression test for the filter pipeline.
-
Sepia is implemented as a raster-space color matrix applied per pixel:
R' = 0.393R + 0.769G + 0.189B G' = 0.349R + 0.686G + 0.168B B' = 0.272R + 0.534G + 0.131B -
Integrated into the existing
image.filter(...)dispatcher -
No dependency on libgd filters — this is a native ruby-libgd extension
With sepia added, ruby-libgd now supports:
- grayscale
- brightness
- contrast
- blur
- pixelation
- edge detection
- photographic color transforms
This moves the project beyond bindings and into the territory of a modern Ruby image processing engine, suitable for:
- dashboards
- reports
- map tiles
- historical GIS rendering
- photo pipelines
Native C-Extension Continuous Integration
ruby-libgd now includes a full native CI pipeline that builds, installs, and tests the gem exactly the same way real users do:
- The gem is built via
gem build - Installed via
gem install - Linked against system
libgd - Tested using RSpec against the installed gem (not the source tree)
This guarantees:
gd/gd.sois correctly packagedrequire "gd"works in real environments- No false positives from Bundler or path-based loading
- Docker, CI, and production behave the same
This moves ruby-libgd to production-grade native gem status.
Line thickness is now correctly propagated to libgd:
img.thickness(4)
img.line(10, 10, 200, 200, color)Exposed the native gdImageCopy function to Ruby as GD::Image#copy(src, dx, dy, sx, sy, w, h).
This enables true raster composition between images, allowing tiles and image regions to be copied into a destination canvas.
This operation is a fundamental building block for:
- Tile stitching
- Image mosaics
- Layer compositing
- GIS and map tile rendering pipelines
The method was registered with the correct Ruby 3.3 arity (7 arguments), ensuring ABI compatibility and preventing dispatch errors during compilation.
This change allows ruby-libgd to be used as a full raster rendering engine rather than a single-image manipulation library.