On this page:
11.1 Loading Images
load-surface
surface?
surface-ptr
surface-destroy!
11.2 Creating Surfaces
make-surface
duplicate-surface
convert-surface
surface->texture
11.3 Surface Properties
surface-width
surface-height
surface-pitch
surface-format
surface-pixels
11.4 Pixel Access
surface-get-pixel
surface-set-pixel!
surface-get-pixel-float
surface-set-pixel-float!
11.5 Bulk Pixel Access
surface-fill-pixels!
call-with-surface-pixels
11.6 Surface Locking
surface-lock!
surface-unlock!
call-with-locked-surface
11.7 Blitting
blit-surface!
blit-surface-scaled!
11.8 Filling and Clearing
fill-surface!
clear-surface!
11.9 Transformations
flip-surface!
scale-surface
11.10 Saving Images
save-png!
save-jpg!
save-bmp!
load-bmp
11.11 Screenshots
render-read-pixels
11.12 Format Detection
image-format
11.13 Color Key and Modulation
set-surface-color-key!
surface-has-color-key?
set-surface-color-mod!
set-surface-alpha-mod!
set-surface-blend-mode!
9.0.0.11

11 Images and Surfaces🔗ℹ

This section covers image loading, saving, and surface operations using SDL_image.

For texture loading directly to GPU, see the Textures section. Surfaces are CPU-side images useful for pixel manipulation, screenshots, and window icons.

11.1 Loading Images🔗ℹ

procedure

(load-surface source    
  [#:type type    
  #:custodian cust])  surface?
  source : (or/c string? path? bytes? input-port?)
  type : (or/c symbol? string? #f) = #f
  cust : custodian? = (current-custodian)
Loads an image file as a software surface.

Supports PNG, JPEG, BMP, GIF, WebP, and many other formats via SDL_image.

The #:type hint specifies the format when loading from bytes or a port (e.g., 'png, 'jpg).

;; Load from file
(define surf (load-surface "image.png"))
 
;; Load from bytes with format hint
(define surf2 (load-surface image-bytes #:type 'png))

procedure

(surface? v)  boolean?

  v : any/c
Returns #t if v is a surface.

procedure

(surface-ptr surf)  cpointer?

  surf : surface?
Returns the underlying SDL surface pointer.

procedure

(surface-destroy! surf)  void?

  surf : surface?
Destroys a surface and frees its memory.

Note: Surfaces are automatically destroyed when their custodian shuts down.

11.2 Creating Surfaces🔗ℹ

procedure

(make-surface width    
  height    
  [#:format format    
  #:custodian cust])  surface?
  width : exact-nonnegative-integer?
  height : exact-nonnegative-integer?
  format : (or/c symbol? exact-nonnegative-integer?) = 'rgba32
  cust : custodian? = (current-custodian)
Creates a new blank surface.

Format symbols include: 'rgba32, 'rgba8888, 'argb8888, 'rgb24.

procedure

(duplicate-surface surf [#:custodian cust])  surface?

  surf : surface?
  cust : custodian? = (current-custodian)
Creates a copy of a surface.

procedure

(convert-surface surf    
  format    
  [#:custodian cust])  surface?
  surf : surface?
  format : (or/c symbol? exact-nonnegative-integer?)
  cust : custodian? = (current-custodian)
Converts a surface to a different pixel format.

procedure

(surface->texture renderer    
  surf    
  [#:custodian cust])  texture?
  renderer : renderer?
  surf : surface?
  cust : custodian? = (current-custodian)
Creates a texture from a surface.

The surface is not destroyed; you can create multiple textures from it.

11.3 Surface Properties🔗ℹ

procedure

(surface-width surf)  exact-integer?

  surf : surface?
Returns the width in pixels.

procedure

(surface-height surf)  exact-integer?

  surf : surface?
Returns the height in pixels.

procedure

(surface-pitch surf)  exact-integer?

  surf : surface?
Returns the pitch (bytes per row).

procedure

(surface-format surf)  symbol?

  surf : surface?
Returns the pixel format as a symbol.

procedure

(surface-pixels surf)  cpointer?

  surf : surface?
Returns a pointer to the raw pixel data.

Only use when the surface is locked.

11.4 Pixel Access🔗ℹ

procedure

(surface-get-pixel surf x y)  
byte? byte? byte? byte?
  surf : surface?
  x : exact-integer?
  y : exact-integer?
Reads a pixel from a surface.

Returns (values r g b a) where each component is 0-255.

procedure

(surface-set-pixel! surf x y r g b [a])  void?

  surf : surface?
  x : exact-integer?
  y : exact-integer?
  r : byte?
  g : byte?
  b : byte?
  a : byte? = 255
Writes a pixel to a surface.

procedure

(surface-get-pixel-float surf x y)  
real? real? real? real?
  surf : surface?
  x : exact-integer?
  y : exact-integer?
Reads a pixel as float values (0.0-1.0).

procedure

(surface-set-pixel-float! surf x y r g b [a])  void?

  surf : surface?
  x : exact-integer?
  y : exact-integer?
  r : real?
  g : real?
  b : real?
  a : real? = 1.0
Writes a pixel using float values (0.0-1.0).

11.5 Bulk Pixel Access🔗ℹ

procedure

(surface-fill-pixels! surf generator)  void?

  surf : surface?
  generator : 
(-> exact-integer? exact-integer?
    (values byte? byte? byte? byte?))
Fills a surface by calling a generator function for each pixel.

The generator receives (x y) and returns (values r g b a).

;; Create a gradient
(surface-fill-pixels! surf
  (lambda (x y)
    (values (quotient (* x 255) width)   ; red gradient
            128                           ; constant green
            (quotient (* y 255) height)  ; blue gradient
            255)))                        ; opaque

procedure

(call-with-surface-pixels surf proc)  any

  surf : surface?
  proc : 
(-> cpointer? exact-integer? exact-integer?
    exact-integer? exact-integer? any)
Low-level access to the pixel buffer.

The procedure receives: (pixels width height pitch bytes-per-pixel).

11.6 Surface Locking🔗ℹ

Some operations require locking the surface first.

procedure

(surface-lock! surf)  #t

  surf : surface?
Locks a surface for direct pixel access.

procedure

(surface-unlock! surf)  void?

  surf : surface?
Unlocks a surface after direct pixel access.

procedure

(call-with-locked-surface surf proc)  any

  surf : surface?
  proc : 
(-> surface? cpointer?
    exact-integer? exact-integer?
    exact-integer? any)
Locks, calls the procedure, then unlocks.

The procedure receives: (surface pixels width height pitch).

11.7 Blitting🔗ℹ

procedure

(blit-surface! src    
  dst    
  [#:src-rect src-rect    
  #:dst-rect dst-rect])  void?
  src : surface?
  dst : surface?
  src-rect : (or/c (list/c real? real? real? real?) #f) = #f
  dst-rect : (or/c (list/c real? real? real? real?) #f) = #f
Copies pixels from source to destination surface.

Rectangles are specified as (list x y w h).

procedure

(blit-surface-scaled! src    
  dst    
  [#:src-rect src-rect    
  #:dst-rect dst-rect    
  #:scale-mode scale-mode])  void?
  src : surface?
  dst : surface?
  src-rect : (or/c (list/c real? real? real? real?) #f) = #f
  dst-rect : (or/c (list/c real? real? real? real?) #f) = #f
  scale-mode : (or/c 'nearest 'linear) = 'nearest
Copies and scales pixels from source to destination.

11.8 Filling and Clearing🔗ℹ

procedure

(fill-surface! surf color [#:rect rect])  void?

  surf : surface?
  color : 
(or/c (list/c byte? byte? byte?)
      (list/c byte? byte? byte? byte?))
  rect : (or/c (list/c real? real? real? real?) #f) = #f
Fills a surface or rectangle with a color.

Color is (list r g b) or (list r g b a).

procedure

(clear-surface! surf r g b [a])  void?

  surf : surface?
  r : real?
  g : real?
  b : real?
  a : real? = 1.0
Clears a surface to a color (using float values 0.0-1.0).

11.9 Transformations🔗ℹ

procedure

(flip-surface! surf mode)  void?

  surf : surface?
  mode : (or/c 'horizontal 'vertical)
Flips a surface in place.

To flip both ways, call twice with different modes.

procedure

(scale-surface surf    
  width    
  height    
  [#:mode mode    
  #:custodian cust])  surface?
  surf : surface?
  width : exact-nonnegative-integer?
  height : exact-nonnegative-integer?
  mode : (or/c 'nearest 'linear) = 'nearest
  cust : custodian? = (current-custodian)
Creates a new surface with scaled contents.

11.10 Saving Images🔗ℹ

procedure

(save-png! surf path)  void?

  surf : surface?
  path : (or/c string? path?)
Saves a surface to a PNG file.

procedure

(save-jpg! surf path [quality])  void?

  surf : surface?
  path : (or/c string? path?)
  quality : exact-nonnegative-integer? = 90
Saves a surface to a JPEG file.

quality is 0-100 (higher = better quality, larger file).

procedure

(save-bmp! surf path)  void?

  surf : surface?
  path : (or/c string? path?)
Saves a surface to a BMP file.

procedure

(load-bmp path [#:custodian cust])  surface?

  path : (or/c string? path?)
  cust : custodian? = (current-custodian)
Loads a BMP image from a file.

For other formats (PNG, JPEG, etc.), use load-surface.

11.11 Screenshots🔗ℹ

procedure

(render-read-pixels renderer    
  [#:custodian cust])  surface?
  renderer : renderer?
  cust : custodian? = (current-custodian)
Reads pixels from the renderer into a new surface.

Use this to take screenshots:

(define screenshot (render-read-pixels ren))
(save-png! screenshot "screenshot.png")

11.12 Format Detection🔗ℹ

procedure

(image-format source)  (or/c symbol? #f)

  source : (or/c bytes? input-port?)
Detects the image format from bytes or a port.

Returns a symbol like 'png, 'jpg, 'gif, or #f if the format is unknown.

11.13 Color Key and Modulation🔗ℹ

procedure

(set-surface-color-key! surf color)  void?

  surf : surface?
  color : (or/c (list/c byte? byte? byte?) #f)
Sets the transparent color for a surface.

Pass #f to disable the color key.

procedure

(surface-has-color-key? surf)  boolean?

  surf : surface?
Returns #t if a color key is set.

procedure

(set-surface-color-mod! surf r g b)  void?

  surf : surface?
  r : byte?
  g : byte?
  b : byte?
Sets color modulation for blit operations.

procedure

(set-surface-alpha-mod! surf alpha)  void?

  surf : surface?
  alpha : byte?
Sets alpha modulation for blit operations.

procedure

(set-surface-blend-mode! surf mode)  void?

  surf : surface?
  mode : (or/c 'none 'blend 'add 'mod 'mul)
Sets the blend mode for blit operations.