stb_image
| Language | C (usable from C++) |
|---|---|
| License | public domain or MIT, your choice |
| Repository | github.com/nothings/stb |
| Documentation | comments at the top of stb_image.h and stb_image_write.h |
| Depends on | nothing |
| Read / write | yes (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:
#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#
#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#
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#
// 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:
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#
stbi_write_png_compression_level = 9; // global, default 8
stbi_write_png("out.png", w, h, 4, pixels, w * 4);
Tips#
- For OpenGL textures, which expect the bottom row first, call
stbi_set_flip_vertically_on_load(1)before loading. stbi_write_png_to_funcwrites into a callback instead of a file, e.g. to build a PNG in memory.