All formats

stb_image

LanguageC (usable from C++)
Licensepublic domain or MIT, your choice
Repositorygithub.com/nothings/stb
Documentationcomments at the top of stb_image.h and stb_image_write.h
Depends onnothing
Read / writeyes (stb_image.h) / yes (stb_image_write.h)

stb_image.h is a single-header image loader for PNG, JPEG, BMP, TGA, GIF, PSD, HDR, PIC and PNM. stb_image_write.h writes PNG, BMP, TGA, JPEG and HDR. Both are popular in games, graphics demos and small tools because they need no build setup.

They don’t read PNG metadata (text, color profiles) and the PNG encoder produces larger files than libpng. Don’t use them on untrusted files in security-sensitive code: the authors don’t target hardened decoding.

Installation#

Copy stb_image.h (and stb_image_write.h to save) into your project. In exactly one .c or .cpp file, define the implementation macro before the include:

C
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"

Other files include the headers without the macros. It’s also available as vcpkg install stb.

Basic usage: load and save a PNG#

C
#include "stb_image.h"
#include "stb_image_write.h"
#include <stdio.h>

int main(void) {
    int w, h, channels;
    // last argument 4: always return RGBA; 0 keeps the file's channel count
    unsigned char *pixels = stbi_load("in.png", &w, &h, &channels, 4);
    if (!pixels) {
        printf("load failed: %s\n", stbi_failure_reason());
        return 1;
    }
    printf("%d x %d, %d channels in file\n", w, h, channels);

    // stride is bytes per row
    if (!stbi_write_png("out.png", w, h, 4, pixels, w * 4)) {
        printf("write failed\n");
    }
    stbi_image_free(pixels);
    return 0;
}

How to get the image size without decoding#

C
int w, h, channels;
if (stbi_info("in.png", &w, &h, &channels)) {
    printf("%d x %d, %d channels\n", w, h, channels);
}

How to load a PNG from memory#

C
// data/len: PNG file contents, e.g. embedded in the executable
int w, h, n;
unsigned char *pixels = stbi_load_from_memory(data, (int)len, &w, &h, &n, 4);

How to load 16-bit PNG files#

stbi_load converts 16-bit images to 8 bits. Use stbi_load_16 to keep the full precision:

C
int w, h, n;
unsigned short *pixels = stbi_load_16("in16.png", &w, &h, &n, 0);
if (stbi_is_16_bit("in16.png")) { /* file has 16-bit channels */ }
stbi_image_free(pixels);

How to make smaller PNG files#

C
stbi_write_png_compression_level = 9;  // global, default 8
stbi_write_png("out.png", w, h, 4, pixels, w * 4);

Tips#