Textures and images
raylib distinguishes two related types: Image is CPU-side pixel data (a
heap-allocated buffer you can read and modify without a GPU or a window), and
Texture2D is a GPU-side handle created by uploading an Image. The typical
flow is: generate or load an Image, manipulate it, then call
load_texture_from_image on RaylibHandle to push it to the GPU.
Both types are RAII resources — they clean up automatically on drop (see RAII and resources).
API surface
Image::load_image— load an image file from disk; returnsResult<Image, …>.Image::gen_image_color— generate a solid-color image in memory; no window needed.Image::gen_image_perlin_noise— procedural Perlin-noise image.Image::draw— CPU-side blit of one image onto another.Image::get_color— read a single pixel’sColorby(x, y).RaylibHandle::load_texture_from_image— upload anImageto the GPU as aTexture2D; requires a window + thread token.RenderTexture2D— off-screen render target; used for render-to-texture workflows.RaylibDraw::draw_texture— draw aTexture2Dat a position with a tint color.
Example
CPU-side image operations (generation and pixel read-back) work without a window or GPU. The example below generates a red image and asserts a pixel value — no display required.
extern crate raylib;
use raylib::prelude::*;
fn main() {
// Generate a 64×64 solid-red Image entirely in CPU memory.
let img = Image::gen_image_color(64, 64, Color::RED);
// Read back a pixel and verify its color.
let pixel = img.get_color(32, 32);
assert_eq!(pixel.r, 255);
assert_eq!(pixel.g, 0);
assert_eq!(pixel.b, 0);
// `img` is dropped here; UnloadImage is called automatically.
}
Uploading to the GPU requires a window:
extern crate raylib;
use raylib::prelude::*;
fn main() {
let (mut rl, thread) = raylib::init()
.size(640, 480)
.title("Texture demo")
.build();
let img = Image::gen_image_color(64, 64, Color::BLUE);
// load_texture_from_image uploads to GPU; img can be dropped afterwards.
let tex = rl.load_texture_from_image(&thread, &img).unwrap();
drop(img); // CPU buffer freed; GPU copy lives on in `tex`.
while !rl.window_should_close() {
let mut d = rl.begin_drawing(&thread);
d.clear_background(Color::RAYWHITE);
d.draw_texture(&tex, 100, 100, Color::WHITE);
}
}
Gotchas
Imageis CPU;Texture2Dis GPU. You cannot modify aTexture2Ddirectly. If you need per-frame CPU edits, keep theImage, modify it, and re-upload withupdate_texture.RenderTexture2DY-flip on readback. The WS4 headless harness reads the software-renderer framebuffer as BGRA with Y-inverted rows and then normalises it for you. If you useload_image_from_screendirectly, be aware of the GL-style bottom-left origin. Seenotes/ws4b-complete.md.- Memory-leak fix in 6.0.
export_image_to_memoryhad a leak in 5.x (backlog #247). It was fixed by PR #250 in WS3 — the buffer is now wrapped asManuallyDrop<Box<[u8]>>and freed correctly.
See also
- Software renderer — headless pixel-probe testing.
- 3D models — textures applied to models.
Imagedocs.rs /Texture2Ddocs.rs
Showcase examples
Showcase examples that exercise this module: