Loomy ๐งถ
The friendly pixel-weaver for Ruby.
Loomy is a modern, high-performance image processing engine for Ruby. Think of it as a master weaver for your images: it takes raw layers (the threads) and weaves them into complex compositions using a smart, declarative DSL.
Built on top of libvips, Loomy doesn't just process images; it optimizes the entire "weaving" process (AST) to ensure your pipelines are as light and fast as silk.
๐ Key Features
-
High Performance: Built on
libvipswith a custom Batch Composition engine that flattens operations into a single efficient pipeline. - Hierarchical Groups: Nest layers and groups to create complex layouts with shared effects.
- Intelligent DSL: Declarative, block-based syntax. Define properties naturally without complex argument lists.
- AST Optimizer: A smart "pre-weaving" layer that prunes invisible layers and pre-calculates geometry before rendering.
- Extensible Effects: Dynamic registry to add your own image processing strategies.
๐ฆ Installation
Add this line to your application's Gemfile:
gem 'loomy'And then execute:
bundle install๐ Usage
1. Generating Images
Loomy offers two ways to get your results: render (write to file) and generate (get a Vips::Image object).
Render to file
Loomy.render("output.png", size: [1200, 630]) do
layer "background.jpg"
endGenerate in-memory (Web Servers / Testing)
# Returns a Vips::Image object
image = Loomy.generate(size: [1200, 630]) do
layer "background.jpg"
end
# Get binary buffer for HTTP response or S3
buffer = image.write_to_buffer(".png")2. Hierarchical Groups
Group layers to apply effects or positioning to a set of nodes collectively.
Loomy.render("banner.png", size: [800, 400]) do
group x: 50, y: 50 do
layer "icon.png", width: 50
layer "text.png", x: 60
# Apply blur to the entire group
blur radius: 2
end
end3. The Smart DSL
Forget about complex argument lists. Describe your image layout naturally:
require 'loomy'
Loomy.render("output.png", size: [1200, 630]) do
# Background
layer "background.jpg" do
fit :cover
blur radius: 10
end
# Overlay
layer "avatar.png" do
x :center
y :center
width "20%"
trim true # Auto-crop transparent borders
end
end4. Reusable Styles
Define common looks and apply them anywhere.
# Define a style
Loomy.define_style :hero_layer do
x 50
y 100
blend :overlay
end
Loomy.render("post.png", size: [1000, 1000]) do
layer "texture.png" do
use :hero_layer # Apply the style
width 500 # Override or extend
end
end5. Custom Effects & Registry
Loomy is extensible. You can register your own libvips processors:
# Register a custom effect
Loomy.register_effect(MyCustomEffectClass, ->(img, effect_node) {
img.my_vips_operation(effect_node.param)
})โก Performance
Loomy is designed for scale. Leveraging libvips' streaming architecture and our proprietary AST optimization, Loomy delivers exceptional throughput:
| Complexity | Throughput (M1) |
|---|---|
| Simple Composites | ~70 images/sec |
| Complex (5+ layers + effects) | ~60 images/sec |
๐บ Roadmap
- Full support for relative geometry (
%,vh,vw) - Rounded corners and masking
- SVG support as layers
- Smart Saliency Masking (Background Removal)
๐ License
The gem is available as open source under the terms of the MIT License.
