class Eagle::Image

Overview

An RGBA image in CPU memory: 8 bits per channel, rows from top to bottom.

Images are what you load, generate, edit and save. To draw one, upload it with Texture.new(image). Eagle decodes PNG, QOI and BMP itself, with no system libraries.

img = Image.new(64, 64, Color::TRANSPARENT)
img.fill_rect(8, 8, 48, 48, Color::RED)
img[32, 32] = Color::WHITE
img.blit(Image.circle(16, Color::YELLOW), 24, 24, blend: true)
tex = Texture.new(img)

img.save("out.png") # format follows the extension: .png, .qoi or .bmp

The .checkerboard, .circle and .gradient helpers make placeholder art, so a prototype can run before any assets exist.

Defined in:

eagle/assets/image.cr

Constructors

Instance Method Summary

Constructor Detail

def self.checkerboard(w : Int32, h : Int32, cell : Int32 = 8, a : Color = Color::WHITE, b : Color = Color::GRAY) : Image #

A checkerboard of two colors, handy as a placeholder or a debug floor.


def self.circle(diameter : Int32, color : Color = Color::WHITE) : Image #

A filled, anti-aliased circle on a transparent background.


def self.decode(data : Bytes, hint : String = "") : Image #

Decodes PNG, QOI or BMP bytes. The format is detected from the data, and hint (a file name) is used only in error messages.


def self.gradient(w : Int32, h : Int32, from : Color, to : Color, horizontal : Bool = false) : Image #

A linear gradient from from to to, top to bottom or left to right.


def self.load(path : String) : Image #

Loads an image file through the asset cache.


def self.new(width : Int32, height : Int32, pixels : Bytes) #

Wraps existing RGBA bytes. pixels must hold width * height * 4 bytes.


def self.new(width : Int32, height : Int32, fill : Color = Color::TRANSPARENT) #

Creates an image filled with one color, transparent by default.


Instance Method Detail

def ==(o : Image) : Bool #

True when sizes and every pixel match.


def [](x : Int, y : Int) : Color #

The color of pixel x, y. Raises when out of bounds.


def []=(x : Int, y : Int, c : Color) #

Sets pixel x, y. Raises when out of bounds, so check #in_bounds? for coordinates you didn't compute yourself.


def []?(x : Int, y : Int) : Color | Nil #

The color of pixel x, y, or nil when out of bounds.


def average(x = 0, y = 0, w = @width, h = @height) : Color #

The average color over a rectangle, or the whole image.


def blit(src : Image, x : Int, y : Int, blend : Bool = false) : self #

Copies src onto this image at x, y. With blend, transparent parts of src let this image show through; without it, pixels are overwritten. Returns self.


def clone : Image #

A deep copy.


def difference(o : Image) : Float64 #

Mean absolute difference per channel, from 0 to 255. Use it in tests to compare rendered frames with a tolerance.


def fill(c : Color) : self #

Fills the whole image with c. Returns self.


def fill_rect(x : Int, y : Int, w : Int, h : Int, c : Color) : self #

Fills a rectangle with c, clipped to the image. Returns self.


def flip_vertical! : self #

Flips the image upside down in place.


def height : Int32 #

Height in pixels.


def in_bounds?(x : Int, y : Int) : Bool #

True when x, y is inside the image.


def index(x : Int, y : Int) : Int32 #

Byte offset of pixel x, y in #pixels.


def pixels : Bytes #

Raw RGBA bytes, row by row from the top. Four bytes per pixel.


def premultiply! : self #

Multiplies color by alpha in place, for premultiplied-alpha blending.


def resized(w : Int, h : Int) : Image #

A copy scaled to w by h with nearest-neighbor sampling, which keeps pixel art crisp.


def save(path : String) : Nil #

Writes the image to path, choosing PNG, QOI or BMP from the extension.


def size : Vec2 #

(width, height).


def sub(x : Int, y : Int, w : Int, h : Int) : Image #

A new image holding the rectangle x, y, w, h.


def width : Int32 #

Width in pixels.