CrImage::Image
Image is a finite rectangular grid of Color::Color values taken from a color model
An Image maps every grid square in a Rectangle to a Color from a Model.
"The pixel at (x, y)" refers to the color of the grid square defined by the points (x, y), (x+1, y), (x+1, y+1) and (x, y+1).
A common mistake is assuming that an Image's bounds start at (0, 0).
For example, an animated GIF contains a sequence of Images, and each Image after the first typically only holds pixel data
for the area that changed, and that area doesn't necessarily start at (0, 0).
The correct way to iterate over an Image m's pixels looks like:
b = m.bounds
b.min.y.upto(b.max.y - 1) do |y|
b.min.x.upto(b.max.x - 1) do |x|
do_stuff_with(m[x, y]) # or call `m.at(x,y)`
end
end
Image implementations do not have to be based on an in-memory slice of pixel data.
For example, a CrImage::Uniform is an Image of enormous bounds and uniform color, whose in-memory representation is simply that color.
Typically, though, programs will want an image based on a Slice. Classes types like CrImage::RGBA and CrImage::Gray etc (Look below into Including Types)
hold slices of pixel data and implement the Image interface.
These types also provide a set(x, y , c : Color::Color) method that allows modifying the image one pixel at a time.
m = CrImage::RGBA.new(CrImage.rect(0,0,640,480))
m[5,5] = Color::RGBA.new(255,0,0,255)) #Or call set method like `m.set(5,5, Color::RGBA.new(255,0,0,255))`
If you're reading or writing a lot of pixel data, it can be more efficient, but more complicated, to access these classes pix field directly.
The slice-based Image implementations also provide a sub_image method, which returns an Image backed by the same array.
Modifying the pixels of a sub-image will affect the pixels of the original image, analogous to how modifying the contents of a
sub-slice s[i0..i1] will affect the contents of the original slice s.
m0 = CrImage::RGBA.new(CrImage.rect(0, 0, 8, 5))
m1 = m0.sub_image(CrImage.rect(1, 2, 5, 5)).as(CrImage::RGBA)
pp "#{m0.bounds.width}, #{m1.bounds.width}" # => 8,4
pp m0.stride == m1.stride # => true
For low-level code that works on an image's Pix field, be aware that ranging over Pix can affect pixels outside an image's bounds.
In the example above, the pixels covered by m1.pix are shaded in blue. Higher-level code, such as the at and set methods or the CrImage::Draw package,
will clip their operations to the image's bounds.
Instance methods
Adds a solid border around the image.
Convenience method that delegates to Util::Border.add_border.
Example:
img = CrImage.read("photo.jpg")
framed = img.add_border(20, CrImage::Color::WHITE)
Adds a border with drop shadow effect.
Convenience method that delegates to Util::Border.add_border_with_shadow.
Example:
img = CrImage.read("photo.jpg")
framed = img.add_border_with_shadow(20)
Adds noise to the image.
Convenience method that delegates to Util::Noise.add_noise.
Example:
img = CrImage.read("photo.jpg")
grainy = img.add_noise(0.1)
Adds a rounded border with optional shadow.
Convenience method that delegates to Util::Border.add_rounded_border.
Example:
img = CrImage.read("photo.jpg")
framed = img.add_rounded_border(20, 30)
Returns the color of the pixel at (x,y).
If coordinates are outside bounds, returns a default color (typically transparent black) rather than raising an exception. This simplifies image processing algorithms.
at(bounds().min.x, bounds().min.y)returns the upper-left pixel of the grid.at(bounds().max.x-1, bounds().max.y-1)returns the lower-right one.
For explicit nil on out-of-bounds, concrete types provide at? method.
Applies EXIF orientation transform using integer value (1-8).
Applies EXIF orientation transform to correct image rotation.
Digital cameras store orientation information in EXIF metadata. This method applies the necessary rotation/flip to display correctly.
Parameters:
orientation: EXIF orientation value (1-8) or Orientation enum
Example:
exif = CrImage::EXIF.read("photo.jpg")
if exif && exif.needs_transform?
img = img.auto_orient(exif.orientation)
end
Applies box blur filter to the image.
Parameters:
radius: Blur radius in pixels (default: 2)
Example:
blurred = img.blur(radius: 3)
Applies box blur in-place (modifies the image directly).
Only works on RGBA images. Returns self for method chaining. More memory-efficient than creating a new image.
Parameters:
radius: Blur radius in pixels (default: 2)
Example:
img.blur!(radius: 3).sharpen!(1.2)
Applies Gaussian blur filter for natural-looking blur.
Parameters:
radius: Blur radius in pixels (default: 5)sigma: Standard deviation (auto-calculated if nil)
Example:
blurred = img.blur_gaussian(radius: 5)
custom = img.blur_gaussian(radius: 5, sigma: 2.0)
Applies Gaussian blur in-place (modifies the image directly).
Only works on RGBA images. Returns self for method chaining.
Example:
img.blur_gaussian!(radius: 5, sigma: 2.0)
bounds returns the domain for which at can return non-zero color.
The bounds do not necessarily contain the point(0,0).
Adjusts image brightness.
Parameters:
adjustment: Brightness change (-255 to 255, negative darkens, positive brightens)
Example:
brighter = img.brightness(50)
darker = img.brightness(-50)
Adjusts brightness in-place (modifies the image directly).
Only works on RGBA images. Returns self for method chaining.
Adjusts image contrast.
Parameters:
factor: Contrast multiplier (< 1.0 decreases, > 1.0 increases, 1.0 = no change)
Example:
high_contrast = img.contrast(1.5)
low_contrast = img.contrast(0.5)
Adjusts contrast in-place (modifies the image directly).
Only works on RGBA images. Returns self for method chaining.
Crops the image to the specified region.
Parameters:
x: Left edge of crop areay: Top edge of crop areawidth: Width of crop areaheight: Height of crop area
Example:
cropped = img.crop(10, 10, 200, 150)
Crops the image to the specified rectangle.
Parameters:
rect: Rectangle defining the crop area
Example:
cropped = img.crop(CrImage.rect(10, 10, 100, 100))
Detects edges in the image using the specified operator.
Parameters:
operator: Edge detection algorithm (Sobel, Prewitt, Roberts, Scharr)threshold: Optional threshold for binary edge map (nil for grayscale)
Example:
edges = img.detect_edges(Transform::EdgeOperator::Sobel, threshold: 50)
Counts different pixels compared to another image.
Applies morphological dilation (fills small dark holes).
Parameters:
kernel_size: Structuring element size (default: 3)shape: Element shape (Rectangle, Cross, Ellipse)
Applies dithering to reduce colors using the specified palette.
Parameters:
palette: Target color palettealgorithm: Dithering algorithm (FloydSteinberg, Atkinson, etc.)
Example:
palette = img.generate_palette(16)
dithered = img.dither(palette, Util::DitheringAlgorithm::FloydSteinberg)
Returns the most dominant color in the image.
Convenience method that delegates to Util::PaletteExtractor.dominant_color.
Example:
img = CrImage.read("photo.jpg")
dominant = img.dominant_color
Draws a circle on the image.
Parameters:
x, y: Center point coordinatesradius: Circle radius in pixelscolor: Circle color (default: black)fill: Fill the circle (default: false, outline only)anti_alias: Enable anti-aliasing (default: false)
Example:
img.draw_circle(200, 150, 50, color: CrImage::Color::RED, fill: true)
Draws a circle using a Point object.
Example:
center = CrImage::Point.new(200, 150)
img.draw_circle(center, 50, color: CrImage::Color::RED, fill: true)
Draws an ellipse on the image.
Parameters:
x, y: Center point coordinatesrx: Horizontal radiusry: Vertical radiuscolor: Ellipse color (default: black)fill: Fill the ellipse (default: false, outline only)anti_alias: Enable anti-aliasing (default: false)
Example:
img.draw_ellipse(200, 150, 80, 40, color: CrImage::Color::BLUE, fill: true)
Draws an ellipse using a Point object.
Example:
center = CrImage::Point.new(200, 150)
img.draw_ellipse(center, 80, 40, color: CrImage::Color::BLUE, fill: true)
Draws a line on the image.
Parameters:
x0, y0: Starting point coordinatesx1, y1: Ending point coordinatescolor: Line color (default: black)thickness: Line thickness in pixels (default: 1)anti_alias: Enable anti-aliasing for smooth edges (default: false)
Example:
img.draw_line(10, 10, 100, 100, color: CrImage::Color::RED, thickness: 2)
Draws a line using tuple coordinates.
Example:
img.draw_line({10, 10}, {100, 100}, color: CrImage::Color::BLUE)
Draws a line using Point objects.
Example:
p1 = CrImage::Point.new(10, 10)
p2 = CrImage::Point.new(100, 100)
img.draw_line(p1, p2, color: CrImage::Color::GREEN)
Draws a polygon on the image.
Parameters:
points: Array of points defining the polygon verticesoutline: Outline color (nil for no outline)fill: Fill color (nil for no fill)anti_alias: Enable anti-aliasing (default: false)
Example:
points = [
CrImage::Point.new(100, 50),
CrImage::Point.new(150, 150),
CrImage::Point.new(50, 150),
]
img.draw_polygon(points, outline: CrImage::Color::BLACK, fill: CrImage::Color::RED)
Draws a rectangle on the image.
Parameters:
x, y: Top-left corner coordinateswidth, height: Rectangle dimensionsstroke: Outline color (nil for no outline)fill: Fill color (nil for no fill)anti_alias: Enable anti-aliasing for outline (default: false)
Example:
img.draw_rect(10, 10, 100, 50, stroke: CrImage::Color::BLACK, fill: CrImage::Color::WHITE)
Draws a rectangle using a Point object.
Example:
top_left = CrImage::Point.new(10, 10)
img.draw_rect(top_left, 100, 50, stroke: CrImage::Color::BLACK, fill: CrImage::Color::WHITE)
Iterates over each pixel coordinate.
Example:
img.each_coordinate do |x, y|
img.set(x, y, CrImage::Color::RED)
end
Iterates over each pixel with coordinates and color value.
Example:
img.each_pixel do |x, y, color|
puts "Pixel at (#{x},#{y}): #{color}"
end
Applies emboss effect for a 3D raised appearance.
Parameters:
angle: Light direction angle in degrees (default: 45.0)depth: Effect intensity (default: 1.0)
Example:
embossed = img.emboss(angle: 45.0, depth: 1.5)
Applies adaptive histogram equalization (CLAHE) for local contrast enhancement.
Parameters:
tile_size: Size of local regions (default: 8)clip_limit: Contrast limiting threshold (default: 2.0)
Example:
enhanced = img.equalize_adaptive(tile_size: 8, clip_limit: 2.0)
Applies morphological erosion (removes small bright spots).
Parameters:
kernel_size: Structuring element size (default: 3)shape: Element shape (Rectangle, Cross, Ellipse)
Extracts dominant colors from the image.
Convenience method that delegates to Util::PaletteExtractor.extract.
Example:
img = CrImage.read("photo.jpg")
colors = img.extract_palette(5)
Extracts dominant colors with their relative frequencies.
Convenience method that delegates to Util::PaletteExtractor.extract_with_weights.
Example:
img = CrImage.read("photo.jpg")
colors = img.extract_palette_with_weights(5)
Resizes image to fill the given dimensions, cropping excess.
The resulting image will be exactly width x height. The image is
scaled to cover the entire area, then center-cropped to fit.
Parameters:
width: Target widthheight: Target heightquality: Resampling quality (default: :bicubic)
Example:
# Fill 800x800 square from a 1920x1080 image (crops sides)
filled = img.fill(800, 800)
# Create social media thumbnail
instagram = img.fill(1080, 1080)
Fills the entire image with a solid color.
Example:
img = CrImage.rgba(400, 300)
img.fill(CrImage::Color::WHITE)
Resizes image to fit within the given dimensions, preserving aspect ratio.
The resulting image will be at most width x height, but may be smaller
in one dimension to maintain the original aspect ratio.
Parameters:
width: Maximum widthheight: Maximum heightquality: Resampling quality (default: :bicubic)
Example:
# Fit a 1920x1080 image into 800x600 box
fitted = img.fit(800, 600) # => 800x450 (maintains 16:9)
# Fit with different quality
fast = img.fit(800, 600, quality: :nearest)
best = img.fit(800, 600, quality: :lanczos)
Flips the image horizontally (mirror left-right).
Example:
flipped = img.flip_horizontal
Flips the image vertically (mirror top-bottom).
Example:
flipped = img.flip_vertical
Generates an optimal color palette from the image.
Parameters:
max_colors: Maximum palette size (default: 256)algorithm: Quantization algorithm (MedianCut, Octree, Popularity)
Example:
palette = img.generate_palette(16, Util::QuantizationAlgorithm::MedianCut)
Converts to grayscale in-place (modifies the image directly).
Only works on RGBA images. Returns self for method chaining.
Computes the histogram of the image.
Returns: Histogram object with statistical methods
Example:
hist = img.histogram
puts "Mean: #{hist.mean}, Median: #{hist.median}"
Checks if visually identical to another image.
Inverts colors in-place (modifies the image directly).
Only works on RGBA images. Returns self for method chaining.
Makes the image seamlessly tileable.
Convenience method that delegates to Util::Tiling.make_seamless.
Example:
img = CrImage.read("texture.png")
seamless = img.make_seamless
Applies morphological closing (dilation followed by erosion).
Fills gaps while preserving shape.
Applies morphological gradient (dilation - erosion).
Detects edges and boundaries.
Applies morphological opening (erosion followed by dilation).
Removes noise while preserving shape.
Calculates Mean Squared Error between this and another image.
Returns: MSE value (lower = more similar)
Detects edges using the Prewitt operator.
Calculates Peak Signal-to-Noise Ratio between this and another image.
Returns: PSNR in dB (higher = more similar)
Replaces all pixels of one color with another.
Resizes the image to the specified dimensions.
Available methods:
:nearest- Fast, pixelated (nearest neighbor):bilinear- Good quality, smooth (default):bicubic- High quality, very smooth:lanczos- Highest quality, sharpest
Example:
resized = img.resize(800, 600)
high_quality = img.resize(800, 600, method: :lanczos)
Detects edges using the Roberts cross operator.
Rotates the image by the specified degrees (90, 180, or 270 only).
For arbitrary angle rotation, see Transform.rotate(angle).
Parameters:
degrees: Rotation angle (must be 0, 90, 180, or 270)
Example:
rotated = img.rotate(90)
Rotates the image 270 degrees clockwise (90 degrees counter-clockwise).
Example:
rotated = img.rotate_270
Adds rounded corners to the image.
Convenience method that delegates to Util::Border.round_corners.
Example:
img = CrImage.read("photo.jpg")
rounded = img.round_corners(20)
Creates a selection mask based on color similarity.
Sets the color of the pixel at (x,y).
If the provided coordinates are not within bounds, this method does nothing (no-op). This simplifies drawing operations that may extend beyond image boundaries.
Sharpens the image by enhancing edges.
Parameters:
amount: Sharpening strength (default: 1.0, range: 0.0-2.0)
Example:
sharpened = img.sharpen(amount: 1.5)
Sharpens the image in-place (modifies the image directly).
Only works on RGBA images. Returns self for method chaining.
Performs smart crop to target dimensions.
Convenience method that delegates to Util::SmartCrop.crop.
Example:
img = CrImage.read("photo.jpg")
thumbnail = img.smart_crop(800, 600)
Detects edges using the Sobel operator.
Example:
edges = img.sobel
binary_edges = img.sobel(threshold: 50)
Calculates Structural Similarity Index between this and another image.
Returns: SSIM value (0.0-1.0, higher = more similar)
Adjusts color temperature (warm/cool tint).
Parameters:
adjustment: Temperature shift (positive = warmer/orange, negative = cooler/blue)
Example:
warmer = img.temperature(30)
cooler = img.temperature(-30)
Creates a square thumbnail of the specified size.
Shorthand for fill(size, size) - creates a square thumbnail by
scaling and center-cropping the image.
Parameters:
size: Width and height of the square thumbnailquality: Resampling quality (default: :bicubic)
Example:
# Create 200x200 avatar thumbnail
avatar = img.thumb(200)
# Create multiple sizes
small = img.thumb(64)
medium = img.thumb(128)
large = img.thumb(256)
Tiles the image in a grid pattern.
Convenience method that delegates to Util::Tiling.tile.
Example:
img = CrImage.read("tile.png")
tiled = img.tile(3, 3)
Tiles the image to fill specific dimensions.
Convenience method that delegates to Util::Tiling.tile_to_size.
Example:
img = CrImage.read("pattern.png")
background = img.tile_to_size(1920, 1080)
Encodes the image to a blurhash string.
Blurhash is a compact representation of a placeholder for an image. Useful for showing blurred previews while full images load.
Parameters:
x_components: Horizontal detail (1-9, default: 4)y_components: Vertical detail (1-9, default: 3)
Example:
hash = img.to_blurhash
hash = img.to_blurhash(x_components: 5, y_components: 4)
Applies vignette effect (darkened edges).
Parameters:
strength: Darkening intensity (0.0-1.0, default: 0.5)radius: Vignette radius (0.0-1.0, default: 0.7)
Example:
vignetted = img.vignette(strength: 0.7, radius: 0.6)
Generates a visual diff against another image.
Executes a block with drawing operations clipped to the specified region.
All drawing operations within the block will be restricted to the rectangular region defined by (x, y, width, height). Pixels outside this region will not be modified.
Parameters:
x: Left edge of clip regiony: Top edge of clip regionwidth: Width of clip regionheight: Height of clip region&block: Block receiving a ClippedImage to draw on
Example:
img = CrImage.rgba(400, 300, CrImage::Color::WHITE)
# Draw a circle that would normally overflow, but gets clipped
img.with_clip(50, 50, 100, 100) do |clipped|
style = CrImage::Draw::CircleStyle.new(CrImage::Color::RED, fill: true)
CrImage::Draw.circle(clipped, CrImage.point(50, 50), 80, style)
end
Executes a block with drawing operations clipped to the specified rectangle.
Parameters:
rect: Rectangle defining the clip region&block: Block receiving a ClippedImage to draw on
Example:
plot_area = CrImage.rect(50, 50, 350, 250)
img.with_clip(plot_area) do |clipped|
# All drawing here is restricted to plot_area
end