module

CrImage

CrImage is a comprehensive 2D image processing library for Crystal.

Provides support for reading, writing, and manipulating images across multiple formats (BMP, PNG, JPEG, GIF, TIFF, WebP, ICO) with no external dependencies.

Example:

# Create and manipulate images
img = CrImage.rgba(400, 300, CrImage::Color::WHITE)
img.draw_circle(200, 150, 50, color: CrImage::Color::RED, fill: true)
CrImage::PNG.write("output.png", img)

# Read and transform images
img = CrImage.read("input.png")
resized = img.resize(800, 600, method: :bilinear)
CrImage::JPEG.write("output.jpg", resized, 85)

Constants

BLACK = Uniform.new(Color::BLACK)

Black is an opaque black uniform image.

OPAQUE = Uniform.new(Color::OPAQUE)

Opaque is a fully opaque uniform image.

SafeMath = Math::Safe
TRANSPARENT = Uniform.new(Color::TRANSPARENT)

Transparent is a fully transparent uniform image.

VERSION = {{ (`shards version \"/tmp/tmp.cefImg/src/src\"`).chomp.stringify.downcase }}
WHITE = Uniform.new(Color::WHITE)

White is an opaque white uniform image.

Class methods

checkerboard(width : Int32, height : Int32, cell_size : Int32 = 8, color1 : Color::Color = Color::RGBA.new(204_u8, 204_u8, 204_u8, 255_u8), color2 : Color::Color = Color::WHITE) : RGBA

Creates a checkerboard pattern image.

Useful for transparency backgrounds or testing.

Parameters:

  • width : Image width
  • height : Image height
  • cell_size : Size of each checker cell (default: 8)
  • color1 : First color (default: light gray)
  • color2 : Second color (default: white)

Returns: RGBA image with checkerboard pattern

Source
compare_images(before : Image, after : Image, divider : Bool = false, divider_width : Int32 = 2, divider_color : Color::Color = Color.rgb(200, 200, 200), spacing : Int32 = 10) : RGBA

Creates before/after comparison.

Convenience method that delegates to Util::Stacking.compare_images.

Example:

comparison = CrImage.compare_images(before, after, divider: true)
Source
create_grid(images : Array(Image), cols : Int32, spacing : Int32 = 10, background : Color::Color = Color::TRANSPARENT) : RGBA

Creates grid layout.

Convenience method that delegates to Util::Stacking.create_grid.

Example:

grid = CrImage.create_grid([img1, img2, img3, img4], cols: 2)
Source
draw_ycbcr(dst : RGBA, r : Rectangle, src : YCbCr, sp : Point) : Bool

draws the YCbCr source image on the RGBA destination image with r.min in dst aligned with sp in src. It reports whether the draw was successful. If it returns false, no dst pixels were changed.

This function assumes that r is entrirely within dst's bounds and the translation of r from dst coordinates space to src coordinate space is entirely within src's bounds.

Source
generate_noise(width : Int32, height : Int32, noise_type : Util::NoiseType = Util::NoiseType::Gaussian, scale : Float64 = 1.0) : RGBA

Generates a noise texture image.

Convenience method that delegates to Util::Noise.generate_noise_texture.

Example:

noise = CrImage.generate_noise(800, 600)
Source
generate_sprite_sheet(images : Array(Image), layout : Util::SpriteLayout = Util::SpriteLayout::Horizontal, spacing : Int32 = 0, background : Color::Color = Color::TRANSPARENT) : Util::SpriteSheet

Generates sprite sheet from array of images.

Convenience method that delegates to Util::SpriteGenerator.generate.

Example:

images = [img1, img2, img3]
sheet = CrImage.generate_sprite_sheet(images)
Source
gradient(width : Int32, height : Int32, start_color : Color::Color, end_color : Color::Color, direction : Symbol = :horizontal) : RGBA

Creates a gradient image.

Parameters:

  • width : Image width
  • height : Image height
  • start_color : Color at the start
  • end_color : Color at the end
  • direction : Gradient direction (:horizontal, :vertical, :diagonal)

Returns: RGBA image with gradient

Source
gray(width : Int32, height : Int32) : Gray

Creates a new 8-bit grayscale image.

Parameters:

  • width : Image width in pixels
  • height : Image height in pixels

Returns: A new Gray image

Source
gray16(width : Int32, height : Int32) : Gray16

Creates a new 16-bit grayscale image.

Parameters:

  • width : Image width in pixels
  • height : Image height in pixels

Returns: A new Gray16 image

Source
nrgba(width : Int32, height : Int32, fill_color : Color::Color) : NRGBA

Creates a new NRGBA image filled with the specified color.

Parameters:

  • width : Image width in pixels
  • height : Image height in pixels
  • fill_color : Color to fill the image with

Returns: A new NRGBA image filled with the color

Source
nrgba(width : Int32, height : Int32) : NRGBA

Creates a new NRGBA (non-premultiplied alpha) image.

Parameters:

  • width : Image width in pixels
  • height : Image height in pixels

Returns: A new NRGBA image

Source
nrgba64(width : Int32, height : Int32) : NRGBA64

Creates a new 64-bit NRGBA image (16 bits per channel, non-premultiplied).

Parameters:

  • width : Image width in pixels
  • height : Image height in pixels

Returns: A new NRGBA64 image

Source
paletted(width : Int32, height : Int32, palette : Color::Palette) : Paletted

Creates a new paletted (indexed color) image.

Parameters:

  • width : Image width in pixels
  • height : Image height in pixels
  • palette : Color palette for the image

Returns: A new Paletted image

Source
point(x : Int32, y : Int32) : Point

Creates a Point from x and y coordinates.

Parameters:

  • x : X coordinate
  • y : Y coordinate

Returns: A new Point

Source
point(tuple : Tuple(Int32, Int32)) : Point

Creates a Point from a tuple.

Parameters:

  • tuple : A tuple of (x, y) coordinates

Returns: A new Point

Source
qr_code(data : String, size : Int32 = 300, error_correction : Symbol | Nil = nil, margin : Int32 = 4, logo : Image | Nil = nil, logo_scale : Float64 = 0.2, logo_border : Int32 = 4) : RGBA

Generates a QR code image from text, optionally with a logo overlay.

Parameters:

  • data : Text to encode
  • size : Target image size in pixels (default: 300)
  • error_correction : Error correction level (default: :medium, or :high if logo provided)
  • margin : Quiet zone in modules (default: 4)
  • logo : Optional logo image to overlay in center
  • logo_scale : Logo size as fraction of QR size (default: 0.2 = 20%)
  • logo_border : White border around logo in pixels (default: 4)

Returns: RGBA image containing the QR code

Example:

# Simple QR code
qr = CrImage.qr_code("https://example.com")

# With options
qr = CrImage.qr_code("Hello", size: 400, error_correction: :high)

# With logo overlay
logo = CrImage::PNG.read("logo.png")
qr = CrImage.qr_code("https://example.com", logo: logo)
Source
read(path : String) : CrImage::Image

Reads and decodes an entire image from a file.

Automatically detects the image format by examining magic bytes. Refer to supported_formats for a list of registered decoders.

Supported formats: BMP, PNG, JPEG, GIF, TIFF, WebP, ICO

Example:

img = CrImage.read("photo.jpg")
puts "#{img.bounds.width}x#{img.bounds.height}"
Source
read(io : IO) : CrImage::Image

Reads and decodes an entire image from an IO stream.

Automatically detects the image format by examining magic bytes. Refer to supported_formats for a list of registered decoders.

Example:

File.open("photo.jpg") do |file|
  img = CrImage.read(file)
end
Source
read_config(path : String) : CrImage::Config

Reads image metadata without decoding the entire image.

This is much faster and uses less memory than read when you only need dimensions and color model information.

Returns: A Config struct with width, height, and color model

Example:

config = CrImage.read_config("large_photo.jpg")
puts "Dimensions: #{config.width}x#{config.height}"
puts "Color model: #{config.color_model.name}"
Source
read_config(io : IO) : CrImage::Config

Reads image metadata from an IO stream without decoding the entire image.

Returns: A Config struct with width, height, and color model

Source
rect(x0 : Int32, y0 : Int32, x1 : Int32, y1 : Int32) : Rectangle

Creates a Rectangle from coordinate pairs.

Convenience factory method that automatically ensures the rectangle is well-formed by swapping coordinates if necessary (min < max).

Parameters:

  • x0 : Left edge x-coordinate
  • y0 : Top edge y-coordinate
  • x1 : Right edge x-coordinate
  • y1 : Bottom edge y-coordinate

Returns: A well-formed Rectangle

Example:

r = CrImage.rect(10, 20, 100, 200)
# Creates Rectangle from (10,20) to (100,200)

# Coordinates are automatically swapped if needed
r2 = CrImage.rect(100, 200, 10, 20) # Same as above
Source
register_format(name : String, magic : Bytes, reader : ImageReader)

Registers a new image format decoder.

This allows extending the library with custom image format support.

Parameters:

  • name : Format name (e.g., "png", "jpeg")
  • magic : Magic bytes for format detection (use '?' for wildcards)
  • reader : ImageReader implementation

Example:

CrImage.register_format("custom", "CUST".to_slice, MyCustomReader.new)
Source
rgba(width : Int32, height : Int32, fill_color : Color::Color) : RGBA

Creates a new RGBA image filled with the specified color.

Convenience method for creating an image with a solid background color.

Parameters:

  • width : Image width in pixels
  • height : Image height in pixels
  • fill_color : Color to fill the entire image with

Returns: A new RGBA image filled with the specified color

Example:

# White background
img = CrImage.rgba(400, 300, CrImage::Color::WHITE)
# Or with custom color
img = CrImage.rgba(400, 300, CrImage::Color.rgb(200, 220, 240))
Source
rgba(width : Int32, height : Int32) : RGBA

Creates a new RGBA image.

Factory method for creating RGBA images with less verbosity. RGBA uses premultiplied alpha for efficient compositing.

Parameters:

  • width : Image width in pixels
  • height : Image height in pixels

Returns: A new RGBA image with transparent black pixels

Example:

img = CrImage.rgba(400, 300)
# Instead of: CrImage::RGBA.new(CrImage.rect(0, 0, 400, 300))
Source
rgba64(width : Int32, height : Int32) : RGBA64

Creates a new 64-bit RGBA image (16 bits per channel).

Parameters:

  • width : Image width in pixels
  • height : Image height in pixels

Returns: A new RGBA64 image

Source
stack_horizontal(images : Array(Image), spacing : Int32 = 0, alignment : Util::VerticalAlignment = Util::VerticalAlignment::Center, background : Color::Color = Color::TRANSPARENT) : RGBA

Stacks images horizontally.

Convenience method that delegates to Util::Stacking.stack_horizontal.

Example:

comparison = CrImage.stack_horizontal([img1, img2, img3])
Source
stack_vertical(images : Array(Image), spacing : Int32 = 0, alignment : Util::HorizontalAlignment = Util::HorizontalAlignment::Center, background : Color::Color = Color::TRANSPARENT) : RGBA

Stacks images vertically.

Convenience method that delegates to Util::Stacking.stack_vertical.

Example:

stacked = CrImage.stack_vertical([img1, img2, img3])
Source
supported_formats

Returns a list of supported image format names.

Example:

puts CrImage.supported_formats
# => ["bmp", "gif", "jpeg", "png", "tiff", "webp", "ico"]
Source
write(path : String, img : Image, quality : Int32 = 90)

Writes an image to a file, auto-detecting format from extension.

Parameters:

  • path : Output file path
  • img : Image to write
  • quality : Quality for lossy formats (default: 90)

Example:

CrImage.write("output.png", img)
CrImage.write("output.jpg", img, quality: 85)
Source
write(io : IO, img : Image, ext : String = ".png")

Writes an image to a IO, auto-detecting format from extension.

Parameters:

  • io : Output IO
  • img : Image to write

Example:

CrImage.write("output.png", img)
CrImage.write("output.jpg", img)
Source
ycbcr_size(r : Rectangle, sub_sample_ratio : YCbCrSubSampleRatio) : Tuple(Int32, Int32, Int32, Int32)
Source

Macros

define_slice_image_type(type_name, color_type, bytes_per_pixel, model_method, at_method, set_method, default_color, opaque_default = false, single_field = "y")
Source

Nested types