Project

loomy

0.0
No release in over 3 years
Loomy is a high-performance, declarative Ruby DSL for image composition and manipulation.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 6.0
~> 13.0

Runtime

~> 2.3
~> 2.7
 Project Readme

Loomy Logo

Loomy ๐Ÿงถ

The friendly pixel-weaver for Ruby.

Gem Version License Tests Status


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 libvips with 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"
end

Generate 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
end

3. 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
end

4. 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
end

5. 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.