All formats

LodePNG

LanguageC and C++
Licensezlib license
Repositorygithub.com/lvandeve/lodepng
Documentationcomments in lodepng.h
Depends onnothing (contains its own zlib / DEFLATE)
Read / writeyes / yes

LodePNG is 2 files, lodepng.cpp and lodepng.h, that decode and encode PNG with no external dependencies. It’s the easiest way to add PNG support to a C or C++ program. Compile the .cpp file as C to use it from C (rename it to lodepng.c).

It decodes all PNG color types, converts them to the format you ask for (8-bit RGBA by default), reads text chunks, and encodes with an automatic choice of color type. Decoding is slower than libpng or libspng.

Installation#

Copy lodepng.cpp and lodepng.h from the repository into your project and compile lodepng.cpp with the rest of your code. It’s also in vcpkg (vcpkg install lodepng) and Conan.

Basic usage: decode and encode#

C++
#include "lodepng.h"
#include <iostream>
#include <vector>

int main() {
    std::vector<unsigned char> image;  // RGBA, 4 bytes per pixel
    unsigned width, height;

    unsigned error = lodepng::decode(image, width, height, "in.png");
    if (error) {
        std::cerr << "decode error " << error << ": " << lodepng_error_text(error) << "\n";
        return 1;
    }
    std::cout << width << " x " << height << "\n";

    // invert colors, keep alpha
    for (size_t i = 0; i < image.size(); i += 4) {
        image[i] = 255 - image[i];
        image[i + 1] = 255 - image[i + 1];
        image[i + 2] = 255 - image[i + 2];
    }

    error = lodepng::encode("out.png", image, width, height);
    if (error) {
        std::cerr << "encode error " << error << ": " << lodepng_error_text(error) << "\n";
        return 1;
    }
    return 0;
}

Using LodePNG from C#

C
#include "lodepng.h"
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    unsigned char *image = NULL;
    unsigned width, height;
    unsigned error = lodepng_decode32_file(&image, &width, &height, "in.png");
    if (error) {
        printf("error %u: %s\n", error, lodepng_error_text(error));
        return 1;
    }
    error = lodepng_encode32_file("out.png", image, width, height);
    free(image);
    return error ? 1 : 0;
}

How to get the size and color type without decoding#

C++
std::vector<unsigned char> png;
lodepng::load_file(png, "in.png");
unsigned w, h;
lodepng::State state;
unsigned error = lodepng_inspect(&w, &h, &state, png.data(), png.size());
if (!error) {
    const LodePNGColorMode &color = state.info_png.color;
    std::cout << w << " x " << h << ", color type " << color.colortype
              << ", bit depth " << color.bitdepth << "\n";
}

How to read text chunks#

C++
std::vector<unsigned char> png, image;
lodepng::load_file(png, "in.png");
lodepng::State state;  // text chunks are read by default (state.decoder.read_text_chunks)
unsigned w, h;
unsigned error = lodepng::decode(image, w, h, state, png);
if (!error) {
    const LodePNGInfo &info = state.info_png;
    for (size_t i = 0; i < info.text_num; i++)
        std::cout << info.text_keys[i] << ": " << info.text_strings[i] << "\n";
    for (size_t i = 0; i < info.itext_num; i++)  // UTF-8 iTXt chunks
        std::cout << info.itext_keys[i] << ": " << info.itext_strings[i] << "\n";
}

How to save a grayscale PNG#

Pass the color type and bit depth of your buffer:

C++
std::vector<unsigned char> gray(width * height);  // 1 byte per pixel
// ... fill gray ...
unsigned error = lodepng::encode("gray.png", gray, width, height, LCT_GREY, 8);

Other color types: LCT_RGB, LCT_RGBA, LCT_GREY_ALPHA, LCT_PALETTE.

Tips#