module

CrImage::Transform

Image transformation and filtering operations.

Provides a comprehensive set of image manipulation functions including:

  • Resizing with multiple interpolation algorithms (nearest, bilinear, bicubic, Lanczos)
  • Rotation (arbitrary angles and optimized 90°/180°/270°)
  • Flipping (horizontal and vertical)
  • Cropping to rectangles
  • Filters (blur, sharpen, Gaussian blur)
  • Adjustments (brightness, contrast, grayscale, inversion)
  • Edge detection (Sobel, Prewitt, Roberts, Scharr)
  • Visual effects (sepia, emboss, vignette, temperature)
  • In-place operations for memory efficiency

Example:

img = CrImage.read("input.png")

# Resize with high quality
resized = img.resize(800, 600, method: :lanczos)

# Rotate 45 degrees
rotated = img.rotate(45.0)

# Apply filters
blurred = img.blur_gaussian(radius: 5)
sharpened = img.sharpen(amount: 1.5)

# Adjust colors
brighter = img.brightness(50)
contrasted = img.contrast(1.2)

# Edge detection
edges = img.sobel

# Visual effects
vintage = img.sepia
embossed = img.emboss

Class methods

auto_orient(src : Image, orientation : Int32) : Image

Applies EXIF orientation transform using integer value.

Convenience overload that accepts raw orientation value (1-8).

Source
auto_orient(src : Image, orientation : EXIF::Orientation) : Image

Applies EXIF orientation transform to correct image rotation.

Digital cameras store orientation information in EXIF metadata to indicate how the image should be displayed. This method applies the necessary rotation and/or flip to display the image correctly.

Parameters:

  • src : The source image to orient
  • orientation : EXIF orientation value (1-8)

Returns: A new Image with correct orientation, or copy if no transform needed

Orientation values:

  • 1: Normal (no transform)
  • 2: Flip horizontal
  • 3: Rotate 180°
  • 4: Flip vertical
  • 5: Transpose (flip horizontal + rotate 270°)
  • 6: Rotate 90° clockwise
  • 7: Transverse (flip horizontal + rotate 90°)
  • 8: Rotate 270° clockwise (90° counter-clockwise)

Example:

img = CrImage::JPEG.read("photo.jpg")
exif = CrImage::EXIF.read("photo.jpg")
if exif
  oriented = CrImage::Transform.auto_orient(img, exif.orientation)
end
Source
blur!(img : Image, radius : Int32) : Nil

Applies box blur in-place without creating a new image.

Modifies the image directly, which is much faster and more memory-efficient than the non-mutating version. Uses a temporary buffer internally but still more efficient than creating a full copy. The original image data is permanently modified.

Parameters:

  • img : The RGBA image to modify (must be RGBA type)
  • radius : Blur radius in pixels (must be positive)

Returns: Nil (modifies image in-place)

Raises: ArgumentError if radius is not positive or image is not RGBA type

Example:

img = CrImage::PNG.read("photo.png").as(CrImage::RGBA)
CrImage::Transform.blur!(img, 5)
Source
blur_box(src : Image, radius : Int32) : Image

Applies a box blur filter to an image.

Box blur is a simple averaging filter that blurs by averaging all pixels within a square kernel. Fast but produces lower quality blur compared to Gaussian. Edge pixels are clamped to image boundaries.

Parameters:

  • src : The source image to blur
  • radius : Blur radius in pixels (must be positive)

Returns: A new blurred Image

Raises: ArgumentError if radius is not positive

Example:

img = CrImage::PNG.read("photo.png")
blurred = CrImage::Transform.blur_box(img, 5)
Source
blur_gaussian(src : Image, radius : Int32, sigma : Float64 | Nil = nil) : Image

Applies Gaussian blur to an image.

Gaussian blur uses a weighted average based on the Gaussian distribution, producing natural-looking blur. Implemented as separable convolution for efficiency. If sigma is not provided, it defaults to radius/3.

Parameters:

  • src : The source image to blur
  • radius : Blur radius in pixels (must be non-negative, 0 returns a copy)
  • sigma : Standard deviation of Gaussian kernel (optional, defaults to radius/3)

Returns: A new blurred Image

Raises: ArgumentError if radius is negative

Example:

img = CrImage::PNG.read("photo.png")
blurred = CrImage::Transform.blur_gaussian(img, 10)
custom_blur = CrImage::Transform.blur_gaussian(img, 10, sigma: 5.0)
Source
blur_gaussian!(img : Image, radius : Int32, sigma : Float64 | Nil = nil) : Nil

Applies Gaussian blur in-place without creating a new image.

Modifies the image directly, which is much faster and more memory-efficient than the non-mutating version. Uses a temporary buffer internally but still more efficient than creating a full copy. The original image data is permanently modified.

Parameters:

  • img : The RGBA image to modify (must be RGBA type)
  • radius : Blur radius in pixels (must be non-negative)
  • sigma : Standard deviation of Gaussian kernel (optional, defaults to radius/3)

Returns: Nil (modifies image in-place)

Raises: ArgumentError if radius is negative or image is not RGBA type

Example:

img = CrImage::PNG.read("photo.png").as(CrImage::RGBA)
CrImage::Transform.blur_gaussian!(img, 10)
Source
brightness(src : Image, adjustment : Int32) : Image

Adjusts the brightness of an image.

Adds a constant value to all RGB channels. Positive values brighten, negative values darken. Values are clamped to 0-255 range. Alpha channel is preserved.

Parameters:

  • src : The source image to adjust
  • adjustment : Brightness adjustment value (-255 to 255)

Returns: A new Image with adjusted brightness

Raises: ArgumentError if adjustment is outside valid range

Example:

img = CrImage::PNG.read("photo.png")
brighter = CrImage::Transform.brightness(img, 50)
darker = CrImage::Transform.brightness(img, -30)
Source
brightness!(img : Image, adjustment : Int32) : Nil

Adjusts brightness in-place without creating a new image.

Modifies the image directly, which is much faster and more memory-efficient than the non-mutating version. The original image data is permanently modified.

Parameters:

  • img : The RGBA image to modify (must be RGBA type)
  • adjustment : Brightness adjustment value (-255 to 255)

Returns: Nil (modifies image in-place)

Raises: ArgumentError if image is not RGBA type

Example:

img = CrImage::PNG.read("photo.png").as(CrImage::RGBA)
CrImage::Transform.brightness!(img, 50)
CrImage::PNG.write("brighter.png", img)
Source
contrast(src : Image, factor : Float64) : Image

Adjusts the contrast of an image.

Scales RGB values around the midpoint (128). Values greater than 1.0 increase contrast, values less than 1.0 decrease contrast. Alpha channel is preserved.

Parameters:

  • src : The source image to adjust
  • factor : Contrast factor (0.0 to 2.0, where 1.0 is no change)

Returns: A new Image with adjusted contrast

Raises: ArgumentError if factor is outside valid range

Example:

img = CrImage::PNG.read("photo.png")
high_contrast = CrImage::Transform.contrast(img, 1.5)
low_contrast = CrImage::Transform.contrast(img, 0.7)
Source
contrast!(img : Image, factor : Float64) : Nil

Adjusts contrast in-place without creating a new image.

Modifies the image directly, which is much faster and more memory-efficient than the non-mutating version. The original image data is permanently modified.

Parameters:

  • img : The RGBA image to modify (must be RGBA type)
  • factor : Contrast factor (0.0 to 2.0, where 1.0 is no change)

Returns: Nil (modifies image in-place)

Raises: ArgumentError if image is not RGBA type

Example:

img = CrImage::PNG.read("photo.png").as(CrImage::RGBA)
CrImage::Transform.contrast!(img, 1.5)
Source
crop(src : Image, rect : Rectangle) : Image

Crops an image to the specified rectangle.

Extracts a rectangular region from the source image. The crop rectangle is automatically clipped to the source image bounds.

Parameters:

  • src : The source image to crop
  • rect : The rectangle defining the crop region

Returns: A new Image containing only the cropped region

Raises: ArgumentError if the crop rectangle is completely outside image bounds

Example:

img = CrImage::PNG.read("photo.png")
crop_rect = CrImage.rect(100, 100, 300, 300)
cropped = CrImage::Transform.crop(img, crop_rect)
Source
detect_edges(src : Image, operator : EdgeOperator = EdgeOperator::Sobel, threshold : Int32 | Nil = nil) : Image

Applies edge detection to an image using the specified operator.

Edge detection highlights areas of rapid intensity change, useful for finding object boundaries, features, and structural information.

Parameters:

  • src : The source image
  • operator : Edge detection operator to use (default: Sobel)
  • threshold : Optional threshold for binary edge map (0-255, nil for gradient magnitude)

Returns: A new grayscale Image showing detected edges

Example:

img = CrImage::PNG.read("photo.png")
edges = CrImage::Transform.detect_edges(img)
binary_edges = CrImage::Transform.detect_edges(img, threshold: 50)
Source
emboss(src : Image, angle : Float64 = 45.0, depth : Float64 = 1.0) : Image

Applies an emboss effect to an image.

Emboss creates a 3D raised appearance by emphasizing edges and converting the image to grayscale with directional lighting.

Parameters:

  • src : The source image
  • angle : Light direction angle in degrees (default: 45.0)
  • depth : Effect strength (default: 1.0, range: 0.5-2.0)

Returns: A new Image with emboss effect

Example:

img = CrImage::PNG.read("photo.png")
embossed = CrImage::Transform.emboss(img)
strong_emboss = CrImage::Transform.emboss(img, depth: 2.0)
Source
flip_horizontal(src : Image) : Image

Flips an image horizontally (mirror effect).

Creates a mirror image by reversing pixels along the horizontal axis. The output dimensions remain the same as the input.

Parameters:

  • src : The source image to flip

Returns: A new Image flipped horizontally

Example:

img = CrImage::PNG.read("face.png")
mirrored = CrImage::Transform.flip_horizontal(img)
Source
flip_vertical(src : Image) : Image

Flips an image vertically (upside down).

Reverses pixels along the vertical axis, turning the image upside down. The output dimensions remain the same as the input.

Parameters:

  • src : The source image to flip

Returns: A new Image flipped vertically

Example:

img = CrImage::PNG.read("photo.png")
upside_down = CrImage::Transform.flip_vertical(img)
Source
grayscale(src : Image) : Image

Converts an image to grayscale.

Uses the luminosity method with standard weights (R: 0.299, G: 0.587, B: 0.114) to convert color images to grayscale. Returns a Gray image.

Parameters:

  • src : The source image to convert

Returns: A new Gray image

Example:

img = CrImage::PNG.read("color_photo.png")
gray = CrImage::Transform.grayscale(img)
CrImage::PNG.write("gray_photo.png", gray)
Source
grayscale!(img : Image) : Nil

Converts image to grayscale in-place (modifies the image directly). Only works on RGBA images for performance. Uses ITU-R BT.709 luminance formula: Y = 0.2126R + 0.7152G + 0.0722*B

Parameters:

  • img : The RGBA image to modify

Returns: Nil (modifies image in-place)

Raises: ArgumentError if image is not RGBA type

Example:

img = CrImage::PNG.read("photo.png").as(CrImage::RGBA)
CrImage::Transform.grayscale!(img)
Source
invert(src : Image) : Image

Inverts the colors of an image (negative effect).

Subtracts each RGB channel value from 255 to create a color negative. Alpha channel is preserved.

Parameters:

  • src : The source image to invert

Returns: A new Image with inverted colors

Example:

img = CrImage::PNG.read("photo.png")
negative = CrImage::Transform.invert(img)
Source
invert!(img : Image) : Nil

Inverts colors in-place without creating a new image.

Modifies the image directly, which is much faster and more memory-efficient than the non-mutating version. The original image data is permanently modified.

Parameters:

  • img : The RGBA image to modify (must be RGBA type)

Returns: Nil (modifies image in-place)

Raises: ArgumentError if image is not RGBA type

Example:

img = CrImage::PNG.read("photo.png").as(CrImage::RGBA)
CrImage::Transform.invert!(img)
Source
prewitt(src : Image, threshold : Int32 | Nil = nil) : Image

Applies Prewitt edge detection (convenience method).

Prewitt operator is similar to Sobel but with equal weighting.

Example:

edges = CrImage::Transform.prewitt(img)
Source
resize_bicubic(src : Image, new_width : Int32, new_height : Int32) : Image

Resizes an image using bicubic (Catmull-Rom) interpolation.

Uses a 4x4 pixel neighborhood for interpolation, producing high quality results with good sharpness. Faster than Lanczos while maintaining excellent quality. Uses separable convolution for efficiency.

Parameters:

  • src : The source image to resize
  • new_width : Target width in pixels (must be positive)
  • new_height : Target height in pixels (must be positive)

Returns: A new Image with the specified dimensions

Raises: ArgumentError if width or height is not positive

Example:

img = CrImage::JPEG.read("photo.jpg")
high_quality = CrImage::Transform.resize_bicubic(img, 1920, 1080)
# Or use the chainable API:
high_quality = img.resize(1920, 1080, method: :bicubic)
Source
resize_bilinear(src : Image, new_width : Int32, new_height : Int32) : Image

Resizes an image using bilinear interpolation.

Provides better quality than nearest neighbor by interpolating between the four nearest pixels. Good balance between speed and quality for most uses.

Parameters:

  • src : The source image to resize
  • new_width : Target width in pixels (must be positive)
  • new_height : Target height in pixels (must be positive)

Returns: A new Image with the specified dimensions

Raises: ArgumentError if width or height is not positive

Example:

img = CrImage::PNG.read("photo.png")
resized = CrImage::Transform.resize_bilinear(img, 800, 600)
# Or use the chainable API:
resized = img.resize(800, 600, method: :bilinear)
Source
resize_lanczos(src : Image, new_width : Int32, new_height : Int32) : Image

Resizes an image using Lanczos-3 interpolation.

Provides the highest quality resizing with excellent detail preservation and minimal aliasing artifacts. Uses a 3-lobe windowed sinc filter. Best for professional photo editing and when quality is paramount. Slower than other methods due to larger kernel size.

Parameters:

  • src : The source image to resize
  • new_width : Target width in pixels (must be positive)
  • new_height : Target height in pixels (must be positive)

Returns: A new Image with the specified dimensions

Raises: ArgumentError if width or height is not positive

Example:

img = CrImage::PNG.read("artwork.png")
print_quality = CrImage::Transform.resize_lanczos(img, 3000, 2000)
# Or use the chainable API:
print_quality = img.resize(3000, 2000, method: :lanczos)
Source
resize_nearest(src : Image, new_width : Int32, new_height : Int32) : Image

Resizes an image using nearest neighbor interpolation.

This is the fastest resizing algorithm but produces lower quality results, especially when upscaling. Best used for pixel art or when speed is critical.

Parameters:

  • src : The source image to resize
  • new_width : Target width in pixels (must be positive)
  • new_height : Target height in pixels (must be positive)

Returns: A new Image with the specified dimensions

Raises: ArgumentError if width or height is not positive

Example:

img = CrImage::PNG.read("input.png")
thumbnail = CrImage::Transform.resize_nearest(img, 100, 100)
# Or use the chainable API:
thumbnail = img.resize(100, 100, method: :nearest)
Source
roberts(src : Image, threshold : Int32 | Nil = nil) : Image

Applies Roberts cross edge detection (convenience method).

Roberts cross uses 2x2 kernels, faster but more sensitive to noise.

Example:

edges = CrImage::Transform.roberts(img)
Source
rotate(src : Image, angle_degrees : Float64, interpolation : RotationInterpolation = RotationInterpolation::Bilinear, background : Color::Color = Color::TRANSPARENT) : Image

Rotates an image by an arbitrary angle (in degrees) clockwise.

The output image is sized to contain the entire rotated image without cropping. Empty areas are filled with the specified background color (default: transparent). For 90°, 180°, 270° rotations, uses optimized fast paths.

Parameters:

  • src : The source image to rotate
  • angle_degrees : Rotation angle in degrees (positive = clockwise)
  • interpolation : Interpolation method (Nearest or Bilinear)
  • background : Color for empty areas (default: transparent)

Returns: A new Image containing the rotated result

Example:

img = CrImage::PNG.read("photo.png")

# Rotate 45 degrees with bilinear interpolation
rotated = CrImage::Transform.rotate(img, 45.0)

# Rotate with nearest neighbor (faster)
rotated = CrImage::Transform.rotate(img, 30.0,
  interpolation: CrImage::Transform::RotationInterpolation::Nearest)

# Rotate with white background
rotated = CrImage::Transform.rotate(img, 15.0,
  background: CrImage::Color::WHITE)
Source
rotate_180(src : Image) : Image

Rotates an image 180 degrees.

The output dimensions remain the same as the input. This is a lossless operation that preserves all pixel data.

Parameters:

  • src : The source image to rotate

Returns: A new Image rotated 180 degrees

Example:

img = CrImage::PNG.read("photo.png")
flipped = CrImage::Transform.rotate_180(img)
Source
rotate_270(src : Image) : Image

Rotates an image 270 degrees clockwise (90 degrees counter-clockwise).

The output dimensions are swapped (width becomes height, height becomes width). This is a lossless operation that preserves all pixel data.

Parameters:

  • src : The source image to rotate

Returns: A new Image rotated 270 degrees clockwise

Example:

img = CrImage::PNG.read("portrait.png")
landscape = CrImage::Transform.rotate_270(img)
Source
rotate_90(src : Image) : Image

Rotates an image 90 degrees clockwise.

The output dimensions are swapped (width becomes height, height becomes width). This is a lossless operation that preserves all pixel data.

Parameters:

  • src : The source image to rotate

Returns: A new Image rotated 90 degrees clockwise

Example:

img = CrImage::PNG.read("landscape.png")
portrait = CrImage::Transform.rotate_90(img)
Source
sepia(src : Image) : Image

Applies a sepia tone effect to an image.

Sepia creates a warm, brownish tone reminiscent of old photographs. Uses standard sepia transformation matrix.

Parameters:

  • src : The source image

Returns: A new Image with sepia tone applied

Example:

img = CrImage::PNG.read("photo.png")
vintage = CrImage::Transform.sepia(img)
Source
sharpen(src : Image, amount : Float64 = 1.0) : Image

Applies a sharpening filter to an image.

Enhances edges and details using an unsharp mask technique. Higher amounts produce more pronounced sharpening. Values above 2.0 may produce artifacts.

Parameters:

  • src : The source image to sharpen
  • amount : Sharpening strength (default: 1.0, typical range: 0.5-2.0)

Returns: A new sharpened Image

Example:

img = CrImage::JPEG.read("photo.jpg")
sharpened = CrImage::Transform.sharpen(img, 1.5)
Source
sharpen!(img : Image, amount : Float64 = 1.0) : Nil

Applies sharpening filter in-place without creating a new image.

Modifies the image directly, which is much faster and more memory-efficient than the non-mutating version. Uses a temporary buffer internally but still more efficient than creating a full copy. The original image data is permanently modified.

Parameters:

  • img : The RGBA image to modify (must be RGBA type)
  • amount : Sharpening strength (default: 1.0, typical range: 0.5-2.0)

Returns: Nil (modifies image in-place)

Raises: ArgumentError if image is not RGBA type

Example:

img = CrImage::PNG.read("photo.png").as(CrImage::RGBA)
CrImage::Transform.sharpen!(img, 1.5)
Source
sobel(src : Image, threshold : Int32 | Nil = nil) : Image

Applies Sobel edge detection (convenience method).

Sobel operator uses 3x3 kernels with smoothing, good for general edge detection.

Example:

edges = CrImage::Transform.sobel(img)
Source
temperature(src : Image, temperature : Int32) : Image

Adjusts color temperature of an image.

Shifts colors toward warm (orange/red) or cool (blue) tones. Useful for correcting white balance or creating mood.

Parameters:

  • src : The source image
  • temperature : Temperature adjustment (-100 to 100, negative=cooler, positive=warmer)

Returns: A new Image with adjusted color temperature

Example:

img = CrImage::PNG.read("photo.png")
warmer = CrImage::Transform.temperature(img, 30)
cooler = CrImage::Transform.temperature(img, -30)
Source
vignette(src : Image, strength : Float64 = 0.5, radius : Float64 = 0.7) : Image

Applies a vignette effect to an image.

Vignette darkens the edges of the image, drawing focus to the center. Common in photography for artistic effect.

Parameters:

  • src : The source image
  • strength : Vignette intensity (default: 0.5, range: 0.0-1.0)
  • radius : Vignette radius as fraction of image size (default: 0.7, range: 0.1-1.0)

Returns: A new Image with vignette effect

Example:

img = CrImage::PNG.read("photo.png")
vignetted = CrImage::Transform.vignette(img)
strong_vignette = CrImage::Transform.vignette(img, strength: 0.8)
Source

Nested types