Skip to content

libpng

UI & GraphicsGraphics / Image ProcessingC

What it is

libpng is the official PNG reference library for C. It provides functions to read, write, and manipulate PNG (Portable Network Graphics) images, supporting compression, filtering, and color types.

libpng allows reading and writing PNG images, handling different color types (grayscale, RGB, RGBA), interlacing, and applying compression. It integrates with other image processing libraries for more advanced workflows.

Installation

sudo apt install libpng-dev

Getting started

The smallest useful thing you can do with it, and what each part means.

Reading a PNG image
#include <png.h>
#include <stdio.h>

int main() {
    FILE *fp = fopen("image.png", "rb");
    if(!fp) return 1;

    png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_infop info = png_create_info_struct(png);
    png_init_io(png, fp);
    png_read_info(png, info);

    int width = png_get_image_width(png, info);
    int height = png_get_image_height(png, info);
    printf("Width: %d, Height: %d\n", width, height);

    png_destroy_read_struct(&png, &info, NULL);
    fclose(fp);
    return 0;
}
Opens a PNG file, reads its header information, and prints the width and height.
Writing a PNG image
#include <png.h>
#include <stdio.h>

int main() {
    FILE *fp = fopen("output.png", "wb");
    if(!fp) return 1;

    png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_infop info = png_create_info_struct(png);
    png_init_io(png, fp);

    int width = 100, height = 100;
    png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
    png_write_info(png, info);

    // Writing image data would go here (omitted for brevity)

    png_write_end(png, info);
    png_destroy_write_struct(&png, &info);
    fclose(fp);
    return 0;
}
Sets up libpng structures and writes PNG header information. Image data writing requires row buffers.

Advanced usage

Where the library earns its place over a simpler alternative.

Handling RGBA pixels
// Read image and access pixel data using png_bytep rows[] and loop through width and height
Demonstrates how to manipulate individual RGBA pixels after reading the PNG image.
Applying compression level
png_set_compression_level(png, Z_BEST_COMPRESSION);
Sets the PNG compression level for writing, improving file size at the cost of CPU usage.
Interlacing support
png_set_interlace_handling(png);
Handles interlaced PNGs correctly when reading or writing images.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

NULL pointer returned by png_create_read_struct
Ensure sufficient memory is available and libpng is initialized correctly.
libpng read error
Check file integrity and ensure it is a valid PNG file.
libpng write error
Ensure the file is writable and the PNG structures are properly initialized.

Best practices

  • Always check return values for file operations and libpng functions.
  • Free libpng structures with png_destroy_read_struct or png_destroy_write_struct to avoid memory leaks.
  • Handle different color types correctly (grayscale, RGB, RGBA).
  • Use appropriate compression levels depending on performance vs file size trade-offs.
  • Consult PNG specifications for proper handling of filters and interlacing.

Background

Why it exists, and what it was reacting to.

libpng was originally developed in 1996 as an open-source reference implementation for the PNG image format. It is widely used in graphics applications, game engines, and software that require handling of PNG images. The library focuses on speed, portability, and compliance with the PNG standard.