C program to write an image in PGM format

The PGM (Portable Gray Map) format is part of the Netpbm package that provides an easy way to store 2D arrays as grayscale images. Unlike complex formats like PNG or JPEG, PGM files use a simple ASCII format that makes them easy to create and read programmatically.

Each PGM file starts with a magic number P2 (for ASCII encoding) followed by dimensions, maximum gray value, and pixel data. The format is human-readable and portable across different platforms.

Syntax

P2
width height
max_gray_value
pixel_values...

PGM File Structure

To write a PGM file, follow these steps −

  • Set magic number P2 for ASCII encoding
  • Add width and height as ASCII decimal numbers
  • Specify maximum gray value (typically 255)
  • Write pixel values row by row, separated by whitespace

Example: Creating a Gradient Image

This example creates a 13x13 grayscale gradient image where each row has a different shade −

#include <stdio.h>

int main() {
    int i, j;
    int w = 13, h = 13;
    
    /* 2D array representing grayscale values (0-255) */
    int image[13][13] = {
        { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 },
        { 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31},
        { 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47},
        { 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63},
        { 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79},
        { 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95 },
        { 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111},
        { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127},
        { 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143},
        { 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159},
        { 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175},
        { 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191},
        { 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207}
    };
    
    FILE* pgmimg;
    pgmimg = fopen("my_pgmimg.pgm", "w"); /* Open file in text mode */
    
    if (pgmimg == NULL) {
        printf("Error opening file!<br>");
        return 1;
    }
    
    /* Write PGM header */
    fprintf(pgmimg, "P2<br>");           /* Magic number */
    fprintf(pgmimg, "%d %d<br>", w, h);  /* Width and height */
    fprintf(pgmimg, "255<br>");          /* Maximum gray value */
    
    /* Write pixel data */
    for (i = 0; i < h; i++) {
        for (j = 0; j < w; j++) {
            fprintf(pgmimg, "%d ", image[i][j]);
        }
        fprintf(pgmimg, "<br>");
    }
    
    fclose(pgmimg);
    printf("PGM image 'my_pgmimg.pgm' created successfully!<br>");
    
    return 0;
}
PGM image 'my_pgmimg.pgm' created successfully!

Generated PGM File Content

The created file my_pgmimg.pgm will contain −

P2
13 13
255
15 15 15 15 15 15 15 15 15 15 15 15 15 
31 31 31 31 31 31 31 31 31 31 31 31 31 
47 47 47 47 47 47 47 47 47 47 47 47 47 
...

Key Points

  • Use "w" mode instead of "wb" for ASCII PGM files
  • Always check if file opening succeeded with NULL comparison
  • Gray values must be between 0 and the specified maximum value
  • Each row should end with a newline for better readability

Conclusion

The PGM format provides a simple way to save 2D arrays as grayscale images. With just a few lines of C code, you can convert numeric data into a viewable image format that works across different platforms.

Updated on: 2026-03-15T10:06:44+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements