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 is an opaque black uniform image.
Opaque is a fully opaque uniform image.
Transparent is a fully transparent uniform image.
White is an opaque white uniform image.
Class methods
Creates a checkerboard pattern image.
Useful for transparency backgrounds or testing.
Parameters:
width: Image widthheight: Image heightcell_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
Creates before/after comparison.
Convenience method that delegates to Util::Stacking.compare_images.
Example:
comparison = CrImage.compare_images(before, after, divider: true)
Creates grid layout.
Convenience method that delegates to Util::Stacking.create_grid.
Example:
grid = CrImage.create_grid([img1, img2, img3, img4], cols: 2)
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.
Generates a noise texture image.
Convenience method that delegates to Util::Noise.generate_noise_texture.
Example:
noise = CrImage.generate_noise(800, 600)
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)
Creates a gradient image.
Parameters:
width: Image widthheight: Image heightstart_color: Color at the startend_color: Color at the enddirection: Gradient direction (:horizontal, :vertical, :diagonal)
Returns: RGBA image with gradient
Creates a new 8-bit grayscale image.
Parameters:
width: Image width in pixelsheight: Image height in pixels
Returns: A new Gray image
Creates a new 16-bit grayscale image.
Parameters:
width: Image width in pixelsheight: Image height in pixels
Returns: A new Gray16 image
Creates a new NRGBA image filled with the specified color.
Parameters:
width: Image width in pixelsheight: Image height in pixelsfill_color: Color to fill the image with
Returns: A new NRGBA image filled with the color
Creates a new NRGBA (non-premultiplied alpha) image.
Parameters:
width: Image width in pixelsheight: Image height in pixels
Returns: A new NRGBA image
Creates a new 64-bit NRGBA image (16 bits per channel, non-premultiplied).
Parameters:
width: Image width in pixelsheight: Image height in pixels
Returns: A new NRGBA64 image
Creates a new paletted (indexed color) image.
Parameters:
width: Image width in pixelsheight: Image height in pixelspalette: Color palette for the image
Returns: A new Paletted image
Creates a Point from x and y coordinates.
Parameters:
x: X coordinatey: Y coordinate
Returns: A new Point
Creates a Point from a tuple.
Parameters:
tuple: A tuple of (x, y) coordinates
Returns: A new Point
Generates a QR code image from text, optionally with a logo overlay.
Parameters:
data: Text to encodesize: 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 centerlogo_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)
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}"
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
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}"
Reads image metadata from an IO stream without decoding the entire image.
Returns: A Config struct with width, height, and color model
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-coordinatey0: Top edge y-coordinatex1: Right edge x-coordinatey1: 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
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)
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 pixelsheight: Image height in pixelsfill_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))
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 pixelsheight: 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))
Creates a new 64-bit RGBA image (16 bits per channel).
Parameters:
width: Image width in pixelsheight: Image height in pixels
Returns: A new RGBA64 image
Stacks images horizontally.
Convenience method that delegates to Util::Stacking.stack_horizontal.
Example:
comparison = CrImage.stack_horizontal([img1, img2, img3])
Stacks images vertically.
Convenience method that delegates to Util::Stacking.stack_vertical.
Example:
stacked = CrImage.stack_vertical([img1, img2, img3])
Returns a list of supported image format names.
Example:
puts CrImage.supported_formats
# => ["bmp", "gif", "jpeg", "png", "tiff", "webp", "ico"]
Writes an image to a file, auto-detecting format from extension.
Parameters:
path: Output file pathimg: Image to writequality: Quality for lossy formats (default: 90)
Example:
CrImage.write("output.png", img)
CrImage.write("output.jpg", img, quality: 85)
Writes an image to a IO, auto-detecting format from extension.
Parameters:
io: Output IOimg: Image to write
Example:
CrImage.write("output.png", img)
CrImage.write("output.jpg", img)
Macros
Nested types
- CrImage::Alpha
- CrImage::Alpha16
- CrImage::BMP
- CrImage::BoundsCheck
- CrImage::BoundsError
- CrImage::CMYK
- CrImage::CircleStyle
- CrImage::ClipContext
- CrImage::ClippedImage
- CrImage::Color
- CrImage::Config
- CrImage::DecompressionGuard
- CrImage::DimensionError
- CrImage::Draw
- CrImage::EXIF
- CrImage::Error
- CrImage::Font
- CrImage::FormatError
- CrImage::GIF
- CrImage::Gray
- CrImage::Gray16
- CrImage::ICO
- CrImage::IOError
- CrImage::Image
- CrImage::InputValidation
- CrImage::InsufficientPointsError
- CrImage::InvalidArgumentError
- CrImage::InvalidGradientError
- CrImage::JPEG
- CrImage::LineStyle
- CrImage::Math
- CrImage::MemoryError
- CrImage::NRGBA
- CrImage::NRGBA64
- CrImage::NYCbCrA
- CrImage::PNG
- CrImage::Paletted
- CrImage::PalettedImage
- CrImage::Pallete
- CrImage::Path
- CrImage::PathStyle
- CrImage::Pipeline
- CrImage::Point
- CrImage::PolygonStyle
- CrImage::RGBA
- CrImage::RGBA64
- CrImage::Rectangle
- CrImage::TIFF
- CrImage::Transform
- CrImage::Uniform
- CrImage::UnknownFormat
- CrImage::UnsupportedError
- CrImage::Util
- CrImage::WEBP
- CrImage::YCbCr
- CrImage::YCbCrSubSampleRatio