Multi-format image loading for SDL2 — adds PNG, JPG, WebP, GIF, SVG, TIFF, ICO, QOI and more to SDL2's native BMP-only loader.
ppm install sdl2-image
What is SDL2_image?
SDL2 on its own can only load BMP files natively. SDL2_image extends SDL2 with
support for 15+ image formats using a single unified API. You call
Load(path)
regardless of format and SDL2_image detects the type automatically from the file content — not
the file extension — so a renamed .png
still loads correctly as PNG.
The most common use case is LoadTexture,
which loads an image file and converts it directly to a GPU texture in one call, skipping the
intermediate surface step entirely.
Supported Formats
| Format | Notes |
| PNG | Full RGBA, transparency, lossless compression — recommended for sprites and UI |
| JPG | Lossy compression, EXIF rotation support — good for backgrounds and photos |
| WebP | Google WebP, both lossy and lossless — smaller files than PNG/JPG |
| GIF | Animated GIF supported; Load returns the first frame by default |
| SVG | Vector graphics rasterized at load time — see SVG note below |
| TIFF | Multi-page TIFF; loads the first page |
| BMP | Windows bitmap (also supported natively by SDL2) |
| ICO | Windows icon files, selects largest available image |
| QOI | Quite OK Image format — fast lossless encoding, no patent issues |
| PCX | Legacy ZSoft PCX format |
| TGA | Truevision TGA, commonly used in game asset pipelines |
| XCF | GIMP native format (flattened) |
| XPM | X11 pixmap format |
Usage Pipeline
Standard pipeline for rendering images:
Init(flags) → Load(path) → SDL_Surface
→ SDL_CreateTextureFromSurface → GPU Texture
→ SDL_RenderCopy → display
Or use LoadTexture(Renderer, path) to skip the surface step entirely.
Always call SDL_FreeSurface and SDL_DestroyTexture when done.
Types
| Type | Underlying | Description |
| TSDLSurface | Integer | SDL_Surface handle — pixel buffer in CPU memory |
| TSDLTexture | Integer | SDL_Texture handle — image uploaded to GPU |
| TSDLRenderer | Integer | SDL_Renderer handle — hardware-accelerated renderer |
| TIMGType | enum | Format identifier: itUnknown, itPNG, itJPG, itWebP, itGIF, itSVG, itTIF, itBMP, itICO, itQOI, itPCX, itTGA, itXCF, itXPM, itLBM, itPNM… |
| TIMGInitFlags | enum | Subsystem init flags: ifJPG ($01), ifPNG ($02), ifTIF ($04), ifWebP ($08), ifJXL ($10), ifAVIF ($20) |
API Reference
Init / Quit / Version
| Function | Description |
| Init(Flags: Integer): Integer | Initialize SDL2_image subsystems. Pass OR of TIMGInitFlags values. Returns 0 on success. |
| Quit | Shut down SDL2_image and free all resources. Call before SDL_Quit. |
| Version: string | Returns the SDL2_image version string, e.g. '2.6.3'. |
Loading
| Function | Description |
| Load(Path): TSDLSurface | Load any supported image format from a file path. Returns SDL_Surface (CPU memory). Returns 0 on failure. |
| LoadTexture(Renderer, Path): TSDLTexture | Load image and convert directly to a GPU texture. Most common function — skips the surface step. |
| LoadFromMemory(Data): TSDLSurface | Load image from an in-memory string/buffer. Format is auto-detected. |
| LoadTextureFromMemory(Renderer, Data): TSDLTexture | Load image from memory directly to GPU texture. |
| LoadPNG(Path): TSDLSurface | Load specifically as PNG. Returns error if file is not valid PNG. |
| LoadJPG(Path): TSDLSurface | Load specifically as JPG/JPEG. |
| LoadSVG(Path, Width, Height): TSDLSurface | Rasterize SVG at the given pixel dimensions. See SVG note below. |
| LoadGIF(Path): TSDLSurface | Load GIF image. Returns the first frame; animated frames require SDL2_image animation API. |
Format Detection
| Function | Description |
| DetectFormat(Path): TIMGType | Inspect file content and return the TIMGType enum value. Does not rely on file extension. |
| IsPNG(Path): Boolean | Returns True if the file content is a valid PNG image. |
| IsJPG(Path): Boolean | Returns True if the file content is a valid JPEG image. |
| IsWebP(Path): Boolean | Returns True if the file content is a valid WebP image. |
Saving
| Function | Description |
| SavePNG(Surface, Path) | Save an SDL_Surface to a PNG file. Lossless. |
| SaveJPG(Surface, Path, Quality) | Save an SDL_Surface to a JPEG file. Quality: 0 (worst) to 100 (best). |
Error
| Function | Description |
| GetError: string | Return the last SDL2_image error message. Check this whenever Load or LoadTexture returns 0. |
Code Example
uses sdl2_image;
var
Renderer: TSDLRenderer;
Tex: TSDLTexture;
begin
{ after SDL_Init and creating window/renderer }
Init(ifPNG or ifJPG or ifWebP);
{ Load any image format with one call }
Tex := LoadTexture(Renderer, 'assets/sprite.png');
if Tex = 0 then
WriteLn('Error: ', GetError);
{ Draw it: SDL_RenderCopy(Renderer, Tex, nil, @destRect) }
{ When done: }
{ SDL_DestroyTexture(Tex) }
Quit;
end.
SVG Loading
SVG rasterization:
SVG files are rasterized at load time — the vector data is converted to pixels immediately.
Use the Width and Height parameters of LoadSVG to control
the output resolution. Passing larger values produces sharper results on high-DPI displays.
SVG is ideal for resolution-independent UI assets such as icons and buttons: load at the
target display size rather than scaling a fixed-resolution PNG.
Format Detection Example
Detection reads the file's magic bytes — not the extension — so it works reliably
even when files are renamed or served without an extension (e.g. HTTP uploads):
uses sdl2_image;
var Path := '/uploads/img'; { no extension }
if IsWebP(Path) then
WriteLn('Detected WebP — using lossless path')
else if IsPNG(Path) then
WriteLn('Detected PNG — full RGBA transparency')
else
begin
var Fmt := DetectFormat(Path);
WriteLn('Format ordinal: ', Fmt);
end;