module

CrImage::Draw

CrImage::Draw provides image composition and drawing operations.

Features:

  • Porter-Duff compositing operators (OVER, SRC)
  • Alpha blending and masking
  • Drawing primitives (lines, circles, ellipses, polygons)
  • Gradient fills (linear and radial)
  • Anti-aliasing support

This module contains image composition functionality for drawing one image onto another with various compositing modes, including support for alpha blending and masks.

Constants

FloydSteinberg = FloydSteinbergS.new

Class methods

arc(img : Image, center : Point, radius : Int32, start_angle : Float64, end_angle : Float64, style : ArcStyle)

Draws an arc (portion of a circle).

Parameters:

  • img : The image to draw on
  • center : Center point of the arc
  • radius : Radius in pixels
  • start_angle : Starting angle in radians (0 = right, PI/2 = down)
  • end_angle : Ending angle in radians
  • style : Arc appearance settings
Source
arrow(img : Image, p1 : Point, p2 : Point, style : ArrowStyle)

Draws a line with arrow heads.

Example:

# Simple arrow
style = CrImage::Draw::ArrowStyle.single(CrImage::Color::BLACK)
CrImage::Draw.arrow(img, CrImage.point(50, 100), CrImage.point(200, 100), style)

# Double-headed arrow
style = CrImage::Draw::ArrowStyle.double(CrImage::Color::RED, thickness: 3)
CrImage::Draw.arrow(img, CrImage.point(50, 150), CrImage.point(200, 150), style)
Source
blend_colors(src : Color::Color, dst : Color::Color, mode : BlendMode) : Color::Color

Blends two colors using the specified blend mode.

Source
bracket(img : Image, p1 : Point, p2 : Point, style : BracketStyle, side : Symbol = :right, curve_amount : Int32 = 10)

Draws a bracket annotation (curly brace style).

Example:

style = CrImage::Draw::BracketStyle.new(color: CrImage::Color::BLACK)
CrImage::Draw.bracket(img, p1, p2, style, side: :right)
Source
callout(img : Image, text : String, box_center : Point, target : Point, style : CalloutStyle, face : Font::Face | Nil = nil, text_color : Color::Color = Color::BLACK)

Draws a callout box with a leader line pointing to a target.

Example:

style = CrImage::Draw::CalloutStyle.new(
  background: CrImage::Color::WHITE,
  border: CrImage::Color::BLACK
)
CrImage::Draw.callout(img, "Note: Important!", box_pos, target_pos, style)
Source
circle(img : Image, center : Point, radius : Int32, style : CircleStyle)

Draws a circle using the midpoint circle algorithm.

Supports both outlined and filled circles with optional anti-aliasing. The algorithm is efficient and produces symmetric circles.

Parameters:

  • img : The image to draw on
  • center : Center point of the circle
  • radius : Circle radius in pixels (must be non-negative)
  • style : Circle appearance settings (color, fill, anti-aliasing)

Raises: ArgumentError if radius is negative

Example:

img = CrImage.rgba(400, 300)
style = CrImage::Draw::CircleStyle.new(CrImage::Color.rgb(0, 255, 0), filled: true)
CrImage::Draw.circle(img, CrImage.point(200, 150), 50, style)
Source
color_scale(img : Image, position : Point, min_value : Float64, max_value : Float64, gradient : LinearGradient, style : ColorScaleStyle, font : CrImage::Font::Face | Nil = nil)

Draws a color scale bar (gradient legend) for heatmaps.

Parameters:

  • img : The image to draw on
  • position : Top-left corner of the scale
  • min_value : Minimum value label
  • max_value : Maximum value label
  • gradient : Gradient to display
  • style : Scale appearance settings
  • font : Font for labels (optional)

Example:

gradient = CrImage::Draw::LinearGradient.new(...)
style = CrImage::Draw::ColorScaleStyle.new(width: 150, height: 15)
CrImage::Draw.color_scale(img, CrImage.point(10, 10), 0.0, 100.0, gradient, style, font)
Source
cubic_bezier(img : Image, p0 : Point, p1 : Point, p2 : Point, p3 : Point, style : BezierStyle)

Draws a cubic bezier curve (two control points).

Parameters:

  • img : The image to draw on
  • p0 : Start point
  • p1 : First control point
  • p2 : Second control point
  • p3 : End point
  • style : Bezier curve appearance settings
Source
dashed_line(img : Image, p1 : Point, p2 : Point, style : DashedLineStyle)

Draws a dashed or dotted line.

Parameters:

  • img : The image to draw on
  • p1 : Starting point
  • p2 : Ending point
  • style : Dashed line appearance settings
Source
data_label(img : Image, text_str : String, position : Point, font : CrImage::Font::Face, font_size : Int32, text_color : Color::Color, background : Color::Color | Nil = nil, padding : Int32 = 2)

Draws a data label with optional background box.

Useful for labeling data points on charts.

Parameters:

  • img : The image to draw on
  • text_str : Label text
  • position : Position for the label
  • font : Font for the label
  • font_size : Font size (for calculating box size)
  • text_color : Text color
  • background : Optional background color
  • padding : Padding around text (if background)
Source
dimension_line(img : Image, p1 : Point, p2 : Point, label : String, style : DimensionStyle, face : Font::Face | Nil = nil, offset : Int32 = 20)

Draws a dimension line with measurements.

Example:

style = CrImage::Draw::DimensionStyle.new(color: CrImage::Color::BLACK)
CrImage::Draw.dimension_line(img, p1, p2, "100 px", style, face, offset: 30)
Source
draw(dst : Image, r : Rectangle, src : Image, sp : Point, op : Op)

Draws a source image onto a destination image using Porter-Duff composition.

This is a convenience method that calls draw_mask with no mask. The rectangle r in the destination is filled with pixels from the source starting at point sp, using the specified composition operator.

Parameters:

  • dst : Destination image to draw onto
  • r : Rectangle in destination to fill
  • src : Source image to draw from
  • sp : Starting point in source image
  • op : Porter-Duff composition operator (e.g., OVER, SRC)

Example:

background = CrImage.rgba(400, 300, CrImage::Color.rgb(255, 255, 255))
logo = CrImage::PNG.read("logo.png")
CrImage::Draw.draw(background, logo.bounds, logo, CrImage.point(0, 0), CrImage::Draw::Op::OVER)
Source
draw_mask(dst : Image, r : Rectangle, src : Image, sp : Point, mask : Image | Nil, mp : Point, op : Op)

Draws a source image onto a destination with an optional mask using Porter-Duff composition.

Aligns r.min in dst with sp in src and mp in mask, then replaces the rectangle r in dst with the result of a Porter-Duff composition. A nil mask is treated as fully opaque. The mask's alpha channel controls the opacity of the source pixels.

Parameters:

  • dst : Destination image to draw onto
  • r : Rectangle in destination to fill
  • src : Source image to draw from
  • sp : Starting point in source image
  • mask : Optional mask image (nil for no mask)
  • mp : Starting point in mask image
  • op : Porter-Duff composition operator

Example:

background = CrImage.rgba(400, 300)
sprite = CrImage::PNG.read("sprite.png")
mask = CrImage::PNG.read("mask.png")
CrImage::Draw.draw_mask(background, sprite.bounds, sprite, CrImage.point(0, 0),
  mask, CrImage.point(0, 0), CrImage::Draw::Op::OVER)
Source
ellipse(img : Image, center : Point, rx : Int32, ry : Int32, style : CircleStyle)

Draws an ellipse using the midpoint ellipse algorithm.

Supports both outlined and filled ellipses with optional anti-aliasing. The algorithm efficiently handles ellipses of any aspect ratio.

Parameters:

  • img : The image to draw on
  • center : Center point of the ellipse
  • rx : Horizontal radius in pixels (must be non-negative)
  • ry : Vertical radius in pixels (must be non-negative)
  • style : Ellipse appearance settings (color, fill, anti-aliasing)

Raises: ArgumentError if either radius is negative

Example:

img = CrImage.rgba(400, 300)
style = CrImage::Draw::CircleStyle.new(CrImage::Color.rgb(0, 0, 255), filled: false)
CrImage::Draw.ellipse(img, CrImage.point(200, 150), 80, 50, style)
Source
fill_bezier_band(img : Image, top_curve : Tuple(Point, Point, Point, Point), bottom_curve : Tuple(Point, Point, Point, Point), color : Color::Color, segments : Int32 = 32, anti_alias : Bool = false)

Fills the area between two bezier curves (for Sankey diagrams).

Creates a filled band shape bounded by two cubic bezier curves. The top curve goes from left to right, bottom curve goes from right to left to form a closed shape.

Parameters:

  • img : The image to draw on
  • top_curve : Top edge bezier (p0, ctrl1, ctrl2, p1)
  • bottom_curve : Bottom edge bezier (p0, ctrl1, ctrl2, p1)
  • color : Fill color
  • segments : Curve resolution (default: 32)
  • anti_alias : Enable anti-aliased edges (default: false)

Example:

# Sankey flow band
top = {
  CrImage.point(100, 100), # start
  CrImage.point(200, 100), # ctrl1
  CrImage.point(300, 150), # ctrl2
  CrImage.point(400, 150), # end
}
bottom = {
  CrImage.point(100, 130), # start
  CrImage.point(200, 130), # ctrl1
  CrImage.point(300, 180), # ctrl2
  CrImage.point(400, 180), # end
}
CrImage::Draw.fill_bezier_band(img, top, bottom, CrImage::Color::BLUE)
Source
fill_bezier_band(img : Image, top_curve : Tuple(Tuple(Float64, Float64), Tuple(Float64, Float64), Tuple(Float64, Float64), Tuple(Float64, Float64)), bottom_curve : Tuple(Tuple(Float64, Float64), Tuple(Float64, Float64), Tuple(Float64, Float64), Tuple(Float64, Float64)), color : Color::Color, segments : Int32 = 32, anti_alias : Bool = false)

Fills the area between two bezier curves (tuple version).

Source
fill_conic_gradient(img : Image, rect : Rectangle, gradient : ConicGradient)

Fills a rectangle with a conic/angular gradient.

Creates a color transition that sweeps around a center point based on angle. Useful for gauge charts, color wheels, and progress indicators.

Parameters:

  • img : The image to draw on
  • rect : Rectangle area to fill with gradient
  • gradient : Conic gradient definition with center, color stops, and start angle

Example:

# Gauge-style gradient (green to yellow to red)
img = CrImage.rgba(400, 400)
gradient = CrImage::Draw::ConicGradient.new(
  CrImage.point(200, 200),
  [
    CrImage::Draw::ColorStop.new(0.0, CrImage::Color.rgb(0, 255, 0)),   # Green
    CrImage::Draw::ColorStop.new(0.5, CrImage::Color.rgb(255, 255, 0)), # Yellow
    CrImage::Draw::ColorStop.new(1.0, CrImage::Color.rgb(255, 0, 0)),   # Red
  ],
  start_angle: -Math::PI # Start from left
)
CrImage::Draw.fill_conic_gradient(img, img.bounds, gradient)
Source
fill_conic_ring(img : Image, center : Point, inner_radius : Int32, outer_radius : Int32, gradient : ConicGradient, start_angle : Float64 = 0.0, end_angle : Float64 = 2.0 * ::Math::PI)

Fills a ring (donut shape) with a conic gradient.

Combines angular gradient with ring shape - perfect for gauge charts. Only fills pixels between inner_radius and outer_radius.

Parameters:

  • img : The image to draw on
  • center : Center point of the ring
  • inner_radius : Inner radius (hole size)
  • outer_radius : Outer radius
  • gradient : Conic gradient for coloring
  • start_angle : Starting angle in radians (default: 0)
  • end_angle : Ending angle in radians (default: 2π for full circle)

Example:

# Gauge chart with gradient fill
gradient = CrImage::Draw::ConicGradient.new(
  CrImage.point(200, 200),
  [
    CrImage::Draw::ColorStop.new(0.0, CrImage::Color.rgb(0, 255, 0)),
    CrImage::Draw::ColorStop.new(1.0, CrImage::Color.rgb(255, 0, 0)),
  ],
  start_angle: -Math::PI * 0.75
)
CrImage::Draw.fill_conic_ring(img, CrImage.point(200, 200), 60, 100, gradient,
  start_angle: -Math::PI * 0.75, end_angle: Math::PI * 0.75)
Source
fill_linear_gradient(img : Image, rect : Rectangle, gradient : LinearGradient)

Fills a rectangle with a linear gradient.

Creates a smooth color transition between gradient stops along a line from the start point to the end point. Colors are interpolated in RGB space.

Parameters:

  • img : The image to draw on
  • rect : Rectangle area to fill with gradient
  • gradient : Linear gradient definition with start/end points and color stops

Example:

img = CrImage.rgba(400, 300)
gradient = CrImage::Draw::LinearGradient.new(
  CrImage.point(0, 0),
  CrImage.point(400, 0),
  [
    {0.0, CrImage::Color.rgb(255, 0, 0)},
    {1.0, CrImage::Color.rgb(0, 0, 255)},
  ]
)
CrImage::Draw.fill_linear_gradient(img, img.bounds, gradient)
Source
fill_path(img : Image, path : Path, color : Color::Color)

Fills a path with a solid color.

Uses scanline fill algorithm on the flattened path. For anti-aliased fills, use fill_path_aa.

Parameters:

  • img : The image to draw on
  • path : The path to fill
  • color : Fill color

Example:

path = CrImage::Draw::Path.new
  .move_to(100, 50)
  .bezier_to(150, 50, 200, 100, 200, 150)
  .line_to(100, 150)
  .close
CrImage::Draw.fill_path(img, path, CrImage::Color::BLUE)
Source
fill_path_aa(img : Image, path : Path, color : Color::Color)

Fills a path with anti-aliased edges.

Uses signed area coverage for smooth edges.

Parameters:

  • img : The image to draw on
  • path : The path to fill
  • color : Fill color
Source
fill_path_blended(img : Image, path : Path, color : Color::Color, mode : BlendMode)

Fills a path with a color using the specified blend mode.

Source
fill_path_gradient(img : Image, path : Path, gradient : LinearGradient | RadialGradient)

Fills a path with a gradient.

Source
fill_path_pattern(img : Image, path : Path, pattern : Pattern)

Fills a path with a pattern.

Source
fill_pie_pattern(img : Image, center : Point, radius : Int32, start_angle : Float64, end_angle : Float64, pattern : Pattern)

Fills a pie slice (filled arc) with a pattern.

Useful for accessible pie charts where color alone shouldn't distinguish slices.

Parameters:

  • img : The image to draw on
  • center : Center point of the pie
  • radius : Radius in pixels
  • start_angle : Starting angle in radians (0 = right, PI/2 = down)
  • end_angle : Ending angle in radians
  • pattern : Fill pattern

Example:

pattern = CrImage::Draw::Pattern.diagonal(CrImage::Color::BLUE, spacing: 6)
CrImage::Draw.fill_pie_pattern(img, center, 100, 0.0, Math::PI/2, pattern)
Source
fill_polygon_aa(img : Image, points : Array(Point), color : Color::Color)

Fills a polygon with anti-aliased edges.

Parameters:

  • img : The image to draw on
  • points : Array of polygon vertices
  • color : Fill color

Example:

points = [
  CrImage.point(100, 50),
  CrImage.point(200, 150),
  CrImage.point(50, 150),
]
CrImage::Draw.fill_polygon_aa(img, points, CrImage::Color::RED)
Source
fill_polygon_blended(img : Image, points : Array(Point), color : Color::Color, mode : BlendMode)

Fills a polygon with a color using the specified blend mode.

Example:

# Overlapping semi-transparent shapes with multiply blend
CrImage::Draw.fill_polygon_blended(img, points, color, CrImage::Draw::BlendMode::Multiply)
Source
fill_polygon_gradient(img : Image, points : Array(Point), gradient : LinearGradient)

Fills a polygon with a linear gradient.

Parameters:

  • img : The image to draw on
  • points : Array of polygon vertices
  • gradient : Linear gradient definition

Example:

points = [CrImage.point(100, 50), CrImage.point(200, 150), CrImage.point(50, 150)]
gradient = CrImage::Draw::LinearGradient.new(
  CrImage.point(50, 50), CrImage.point(200, 150),
  [CrImage::Draw::ColorStop.new(0.0, CrImage::Color::RED),
   CrImage::Draw::ColorStop.new(1.0, CrImage::Color::BLUE)]
)
CrImage::Draw.fill_polygon_gradient(img, points, gradient)
Source
fill_polygon_gradient(img : Image, points : Array(Point), gradient : RadialGradient)

Fills a polygon with a radial gradient.

Source
fill_polygon_pattern(img : Image, points : Array(Point), pattern : Pattern)

Fills a polygon with a pattern.

Example:

pattern = CrImage::Draw::Pattern.diagonal(CrImage::Color::BLUE, spacing: 6)
CrImage::Draw.fill_polygon_pattern(img, points, pattern)
Source
fill_radial_gradient(img : Image, rect : Rectangle, gradient : RadialGradient)

Fills a rectangle with a radial gradient.

Creates a circular color transition radiating from a center point. Colors are interpolated in RGB space based on distance from center.

Parameters:

  • img : The image to draw on
  • rect : Rectangle area to fill with gradient
  • gradient : Radial gradient definition with center, radius, and color stops

Example:

img = CrImage.rgba(400, 300)
gradient = CrImage::Draw::RadialGradient.new(
  CrImage.point(200, 150),
  150,
  [
    {0.0, CrImage::Color.rgb(255, 255, 0)},
    {1.0, CrImage::Color.rgb(255, 0, 0)},
  ]
)
CrImage::Draw.fill_radial_gradient(img, img.bounds, gradient)
Source
fill_rect_pattern(img : Image, rect : Rectangle, pattern : Pattern)

Fills a rectangle with a pattern.

Source
fill_ring_pattern(img : Image, center : Point, inner_radius : Int32, outer_radius : Int32, start_angle : Float64, end_angle : Float64, pattern : Pattern)

Fills a ring slice (donut segment) with a pattern.

Useful for accessible donut charts where color alone shouldn't distinguish slices.

Parameters:

  • img : The image to draw on
  • center : Center point of the ring
  • inner_radius : Inner radius in pixels (hole size)
  • outer_radius : Outer radius in pixels
  • start_angle : Starting angle in radians
  • end_angle : Ending angle in radians
  • pattern : Fill pattern

Example:

pattern = CrImage::Draw::Pattern.crosshatch(CrImage::Color::RED, spacing: 8)
CrImage::Draw.fill_ring_pattern(img, center, 50, 100, 0.0, Math::PI/2, pattern)
Source
hexagon(img : Image, center : Point, radius : Int32, style : PolygonStyle, rotation : Float64 = 0.0)

Draws a hexagon (flat-top by default)

Source
legend_box(img : Image, position : Point, items : Array(LegendItem), style : LegendStyle, font : CrImage::Font::Face | Nil = nil) : Rectangle

Draws a chart legend box with color swatches and labels.

Parameters:

  • img : The image to draw on
  • position : Top-left corner of the legend
  • items : Array of legend items (label + color/pattern)
  • style : Legend appearance settings
  • font : Font face for labels (optional)

Returns: Rectangle bounds of the drawn legend

Example:

items = [
  CrImage::Draw::LegendItem.new("Sales", CrImage::Color::BLUE),
  CrImage::Draw::LegendItem.new("Costs", CrImage::Color::RED),
]
style = CrImage::Draw::LegendStyle.new(background: CrImage::Color::WHITE)
CrImage::Draw.legend_box(img, CrImage.point(10, 10), items, style, font)
Source
line(img : Image, p1 : Point, p2 : Point, style : LineStyle)

Draws a line from one point to another.

Supports multiple rendering modes based on style settings:

  • Thin lines (thickness=1, no anti-aliasing): Uses fast Bresenham algorithm
  • Thick lines: Draws parallel lines with perpendicular offset
  • Anti-aliased lines: Uses Wu's algorithm for smooth edges
  • Thick anti-aliased lines: Uses polygon-based stroke with AA edges

Parameters:

  • img : The image to draw on
  • p1 : Starting point
  • p2 : Ending point
  • style : Line appearance settings (color, thickness, anti-aliasing)

Example:

img = CrImage.rgba(400, 300)
style = CrImage::Draw::LineStyle.new(CrImage::Color.rgb(255, 0, 0), thickness: 2)
CrImage::Draw.line(img, CrImage.point(10, 10), CrImage.point(100, 100), style)
Source
marker(img : Image, center : Point, style : MarkerStyle)

Draws a marker at the specified position.

Example:

# Scatter plot markers
style = CrImage::Draw::MarkerStyle.filled(CrImage::Draw::MarkerType::Circle, CrImage::Color::RED)
data_points.each do |point|
  CrImage::Draw.marker(img, point, style)
end
Source
markers(img : Image, points : Array(Point), style : MarkerStyle)

Draw multiple markers at once (for scatter plots)

Source
pentagon(img : Image, center : Point, radius : Int32, style : PolygonStyle, rotation : Float64 = (-::Math::PI) / 2)

Draws a pentagon

Source
pie(img : Image, center : Point, radius : Int32, start_angle : Float64, end_angle : Float64, style : ArcStyle)

Draws a pie slice (filled arc with lines to center).

Parameters:

  • img : The image to draw on
  • center : Center point of the pie
  • radius : Radius in pixels
  • start_angle : Starting angle in radians
  • end_angle : Ending angle in radians
  • style : Pie appearance settings
Source
polygon(img : Image, points : Array(Point), style : PolygonStyle)

Draws a polygon from an array of points.

Supports both outlined and filled polygons. Filled polygons use scanline filling for efficiency. Requires at least 3 points to form a valid polygon.

Parameters:

  • img : The image to draw on
  • points : Array of points defining the polygon vertices
  • style : Polygon appearance settings (color, fill, outline)

Raises: ArgumentError if fewer than 3 points are provided

Example:

img = CrImage.rgba(400, 300)
triangle = [
  CrImage.point(200, 50),
  CrImage.point(100, 200),
  CrImage.point(300, 200),
]
style = CrImage::Draw::PolygonStyle.new(CrImage::Color.rgb(255, 255, 0), filled: true)
CrImage::Draw.polygon(img, triangle, style)
Source
polyline(img : Image, points : Array(Point), style : LineStyle)

Draws connected line segments through an array of points.

Parameters:

  • img : The image to draw on
  • points : Array of points to connect
  • style : Line appearance settings

Example:

points = [CrImage.point(10, 10), CrImage.point(50, 30), CrImage.point(90, 20)]
style = CrImage::Draw::LineStyle.new(CrImage::Color::BLUE, thickness: 2)
CrImage::Draw.polyline(img, points, style)
Source
quadratic_bezier(img : Image, p0 : Point, p1 : Point, p2 : Point, style : BezierStyle)

Draws a quadratic bezier curve (one control point).

Parameters:

  • img : The image to draw on
  • p0 : Start point
  • p1 : Control point
  • p2 : End point
  • style : Bezier curve appearance settings
Source
rectangle(img : Image, rect : Rectangle, style : RectStyle)

Draws a rectangle with optional rounded corners.

Parameters:

  • img : The image to draw on
  • rect : Rectangle bounds
  • style : Rectangle appearance settings
Source
regular_polygon(img : Image, center : Point, radius : Int32, sides : Int32, style : PolygonStyle, rotation : Float64 = 0.0)

Draws a regular polygon (equilateral triangle, square, pentagon, hexagon, etc.)

Parameters:

  • img : The image to draw on
  • center : Center point of the polygon
  • radius : Distance from center to vertices
  • sides : Number of sides (3 = triangle, 4 = square, 5 = pentagon, etc.)
  • style : Polygon appearance settings
  • rotation : Rotation angle in radians (default 0, pointing right)

Raises: ArgumentError if sides < 3 or radius < 0

Source
ring_slice(img : Image, center : Point, inner_radius : Int32, outer_radius : Int32, start_angle : Float64, end_angle : Float64, style : RingStyle)

Draws a ring slice (donut segment) between two radii.

This is useful for donut charts where you need a hollow center. The slice is drawn between inner_radius and outer_radius within the specified angle range.

Parameters:

  • img : The image to draw on
  • center : Center point of the ring
  • inner_radius : Inner radius in pixels (hole size)
  • outer_radius : Outer radius in pixels
  • start_angle : Starting angle in radians (0 = right, PI/2 = down)
  • end_angle : Ending angle in radians
  • style : Ring appearance settings

Example:

# Draw a donut chart segment
style = CrImage::Draw::RingStyle.new(CrImage::Color::RED, fill: true)
CrImage::Draw.ring_slice(img, center, 50, 100, 0.0, Math::PI/2, style)
Source
rounded_rect(img : Image, rect : Rectangle, radii : CornerRadii, fill : Color::Color | Nil = nil, stroke : Color::Color | Nil = nil, stroke_thickness : Int32 = 1)

Draws a rounded rectangle with per-corner radius control.

Example:

# Bar chart with rounded top only
CrImage::Draw.rounded_rect(img, rect,
  CrImage::Draw::CornerRadii.top(10),
  fill: CrImage::Color::BLUE)

# Custom per-corner radii
CrImage::Draw.rounded_rect(img, rect,
  CrImage::Draw::CornerRadii.new(top_left: 20, top_right: 5, bottom_right: 20, bottom_left: 5),
  fill: CrImage::Color::RED, stroke: CrImage::Color::BLACK)
Source
spline(img : Image, points : Array(Point), style : BezierStyle, tension : Float64 = 0.5)

Draws a bezier spline through multiple points using Catmull-Rom interpolation.

Parameters:

  • img : The image to draw on
  • points : Array of points to pass through
  • style : Bezier curve appearance settings
  • tension : Curve tension (0.0 = sharp corners, 1.0 = smooth)
Source
spline_flatten(points : Array(Point), tension : Float64 = 0.5, segments_per_span : Int32 = 16) : Array(Point)

Flattens a Catmull-Rom spline to an array of points.

Useful for fills, clipping paths, hit testing, or any operation that needs the interpolated points without drawing.

Parameters:

  • points : Control points the spline passes through
  • tension : Curve tension (0.0 = sharp corners, 1.0 = smooth)
  • segments_per_span : Number of line segments per curve span (default: 16)

Returns: Array of interpolated points along the spline

Example:

control_points = [CrImage.point(10, 50), CrImage.point(50, 20), CrImage.point(90, 60)]
curve_points = CrImage::Draw.spline_flatten(control_points, tension: 0.5)
# Use curve_points for fills, hit testing, etc.
Source
square(img : Image, center : Point, radius : Int32, style : PolygonStyle, rotation : Float64 = ::Math::PI / 4)

Draws a square (rotated 45° by default to have flat top)

Source
square_bracket(img : Image, p1 : Point, p2 : Point, style : BracketStyle, side : Symbol = :right)

Draws a simple brace/bracket (square style).

Source
stroke_arc_gradient(img : Image, center : Point, radius : Int32, start_angle : Float64, end_angle : Float64, stops : Array(ColorStop), thickness : Int32 = 1)

Strokes an arc with gradient color.

Example:

# Progress arc (green to red)
stops = [
  CrImage::Draw::ColorStop.new(0.0, CrImage::Color::GREEN),
  CrImage::Draw::ColorStop.new(1.0, CrImage::Color::RED),
]
CrImage::Draw.stroke_arc_gradient(img, center, radius, 0.0, Math::PI, stops, thickness: 5)
Source
stroke_bezier_gradient(img : Image, curve : CubicBezier, stops : Array(ColorStop), thickness : Int32 = 1, segments : Int32 = 32)

Strokes a bezier curve with gradient color.

Source
stroke_line_gradient(img : Image, p1 : Point, p2 : Point, stops : Array(ColorStop), thickness : Int32 = 1)

Strokes a line with gradient color.

Source
stroke_path(img : Image, path : Path, style : PathStyle)

Strokes a path outline.

Parameters:

  • img : The image to draw on
  • path : The path to stroke
  • style : Stroke appearance settings
Source
stroke_path_gradient(img : Image, path : Path, stops : Array(ColorStop), thickness : Int32 = 1, anti_alias : Bool = false)

Strokes a path with a gradient color.

The gradient is applied along the path length, useful for:

  • Progress indicators
  • Line charts showing value intensity
  • Decorative effects

Example:

path = CrImage::Draw::Path.new
  .move_to(50, 100)
  .bezier_to(150, 50, 250, 150, 350, 100)

stops = [
  CrImage::Draw::ColorStop.new(0.0, CrImage::Color::GREEN),
  CrImage::Draw::ColorStop.new(0.5, CrImage::Color::YELLOW),
  CrImage::Draw::ColorStop.new(1.0, CrImage::Color::RED),
]

CrImage::Draw.stroke_path_gradient(img, path, stops, thickness: 3)
Source
stroke_ring_gradient(img : Image, center : Point, inner_radius : Int32, outer_radius : Int32, start_angle : Float64, end_angle : Float64, stops : Array(ColorStop))

Strokes a ring/donut arc with gradient (for gauge charts).

Source
text(img : Image, text_str : String, position : Point, face : CrImage::Font::Face, color : Color::Color)

Draws text on an image at the specified position.

This is a convenience method that creates a Font::Drawer internally.

Parameters:

  • img : The image to draw on
  • text : The text string to draw
  • position : Position for the text baseline
  • face : Font face to use
  • size : Font size (used to scale if face was created at different size)
  • color : Text color

Example:

font = FreeType::TrueType.load("font.ttf")
face = FreeType::TrueType.new_face(font, 24.0)
CrImage::Draw.text(img, "Hello!", CrImage.point(10, 50), face, CrImage::Color::BLACK)
Source
text_on_arc(img : Image, text : String, center : Point, radius : Int32, start_angle : Float64, end_angle : Float64, face : Font::Face, color : Color::Color, align : Symbol = :center, text_offset : Int32 = 0)

Draws text along a circular arc.

Parameters:

  • img : Image to draw on
  • text : Text to render
  • center : Center of the arc
  • radius : Radius of the arc (text baseline position)
  • start_angle : Starting angle in radians
  • end_angle : Ending angle in radians
  • face : Font face
  • color : Text color
  • align : Text alignment on arc (:start, :center, :end)
  • text_offset : Radial offset from arc (negative = toward center, positive = away)
Source
text_on_curve(img : Image, text : String, curve : CubicBezier, face : Font::Face, color : Color::Color, offset : Float64 = 0.0, text_offset : Int32 = 0)

Draws text along a curved path (bezier curve or arc).

Each character is positioned and rotated to follow the curve tangent. Useful for circular labels around pie/donut charts, curved axis labels.

Parameters:

  • img : Image to draw on
  • text : Text to render
  • curve : Cubic bezier curve to follow
  • face : Font face
  • color : Text color
  • offset : Starting position along curve (0.0 = auto-center)
  • text_offset : Perpendicular offset from curve (negative = above, positive = below)

Example:

# Text along a bezier curve, positioned above the line
curve = CrImage::Draw::CubicBezier.new(
  {50.0, 200.0}, {150.0, 50.0}, {250.0, 50.0}, {350.0, 200.0}
)
CrImage::Draw.text_on_curve(img, "Hello Curved World!", curve, face, color, text_offset: -20)
Source
thick_curve(img : Image, points : Array(Point), color : Color::Color, thickness : Int32, tension : Float64 = 0.5)

Draws a thick anti-aliased curve through multiple points.

This is optimized for thick curves (like KDE lines in histograms) and produces smooth results without gaps or artifacts.

Parameters:

  • img : The image to draw on
  • points : Array of points the curve passes through
  • color : Curve color
  • thickness : Line thickness in pixels
  • tension : Curve tension (0.0 = sharp corners, 1.0 = smooth)

Example:

points = [CrImage.point(10, 50), CrImage.point(50, 20), CrImage.point(90, 60)]
CrImage::Draw.thick_curve(img, points, CrImage::Color::BLUE, 4)
Source
triangle(img : Image, center : Point, radius : Int32, style : PolygonStyle, rotation : Float64 = (-::Math::PI) / 2)

Draws an equilateral triangle

Source
x_axis(img : Image, start_point : Point, end_point : Point, min_value : Float64, max_value : Float64, style : AxisStyle, font : CrImage::Font::Face | Nil = nil, chart_height : Int32 = 0)

Draws an X axis with ticks and optional labels.

Parameters:

  • img : The image to draw on
  • start_point : Left end of the axis
  • end_point : Right end of the axis
  • min_value : Minimum axis value
  • max_value : Maximum axis value
  • style : Axis appearance settings
  • font : Font for labels (optional)
  • chart_height : Height of chart area for grid lines (optional)
Source
y_axis(img : Image, start_point : Point, end_point : Point, min_value : Float64, max_value : Float64, style : AxisStyle, font : CrImage::Font::Face | Nil = nil, chart_width : Int32 = 0)

Draws a Y axis with ticks and optional labels.

Parameters:

  • img : The image to draw on
  • start_point : Bottom end of the axis
  • end_point : Top end of the axis
  • min_value : Minimum axis value
  • max_value : Maximum axis value
  • style : Axis appearance settings
  • font : Font for labels (optional)
  • chart_width : Width of chart area for grid lines (optional)
Source

Nested types