PGM Image Viewer - Python Programming Exercise

In this exercise, you will develop a Python program to create a utility that reads and displays images in the PGM format, which is a version of the NetPBM image formats specifically for grayscale images. This exercise is perfect for practicing file handling, byte manipulation, and data visualization in Python. By implementing this program, you will gain hands-on experience in handling file operations, byte manipulation, and data visualization in Python. This exercise not only reinforces your understanding of file handling but also helps you develop efficient coding practices for managing user interactions.

 Category

Managing Files

 Exercise

PGM Image Viewer

 Objective

Develop a Python program to create a utility that reads and displays images in the PGM format, which is a version of the NetPBM image formats specifically for grayscale images.

The header of a PGM file starts with a line containing either P2 (for ASCII data) or P5 (for binary data).

The second line contains the width and height, separated by a space.

The third line contains the maximum intensity value, typically 255, but it could be another value like 15.

Following the header, the image data begins. In ASCII format (P2), the data consists of numbers from 0 to 255 separated by spaces and possibly newlines. In binary format (P5), the data consists of contiguous bytes ranging from 0 (black) to 255 (white).

You need to create a program that can read a file in binary PGM format (header P5), without comments, with 255 shades of gray (but with varying width and height). Additionally, the program should represent the grayscale values in the console as follows:

- If the intensity is greater than 200, display a blank space.

- If it is between 150 and 199, display a dot.

- If it is between 100 and 149, display a dash (-).

- If it is between 50 and 99, display an equals sign (=).

- If it is between 0 and 49, display a pound sign (#).

The name of the file to be analyzed must be read from the command line, not prompted by the user or pre-set.

 Example Python Exercise

 Copy Python Code
import sys

def read_pgm(filename):
    """
    Reads a PGM (P5) binary file and returns its width, height, max intensity, and pixel data.
    """
    try:
        with open(filename, "rb") as file:
            # Read magic number
            magic_number = file.readline().strip()
            if magic_number != b"P5":
                raise ValueError("File is not in P5 binary PGM format.")

            # Read dimensions (width and height)
            dimensions = file.readline().strip()
            width, height = map(int, dimensions.split())

            # Read maximum intensity value
            max_intensity = int(file.readline().strip())
            if max_intensity != 255:
                raise ValueError("This program only supports max intensity of 255.")

            # Read image data
            pixel_data = file.read()
            if len(pixel_data) != width * height:
                raise ValueError("Mismatch between pixel data and image dimensions.")

            return width, height, pixel_data

    except FileNotFoundError:
        print(f"Error: File '{filename}' not found.")
        sys.exit(1)
    except Exception as e:
        print(f"Error: {str(e)}")
        sys.exit(1)


def display_pgm_image(width, height, pixel_data):
    """
    Displays PGM image pixel data as symbols based on intensity ranges.
    """
    intensity_map = {
        (200, 255): " ",
        (150, 199): ".",
        (100, 149): "-",
        (50, 99): "=",
        (0, 49): "#",
    }

    for y in range(height):
        row = ""
        for x in range(width):
            intensity = pixel_data[y * width + x]
            for range_min, range_max in intensity_map:
                if range_min <= intensity <= range_max:
                    row += intensity_map[(range_min, range_max)]
                    break
        print(row)


if __name__ == "__main__":
    # Ensure the filename is provided as a command-line argument
    if len(sys.argv) != 2:
        print("Usage: python pgm_viewer.py ")
        sys.exit(1)

    # Read the PGM file
    filename = sys.argv[1]
    width, height, pixel_data = read_pgm(filename)

    # Display the image
    display_pgm_image(width, height, pixel_data)

 Output

A binary PGM file with the following header:

P5
6 4
255

And pixel data (as binary values):

200 180 120 80 30 10
250 190 140 90 40 20
220 170 130 70 60 50
210 160 110 100 0 5

Execution:

python pgm_viewer.py example.pgm

Output:

  . - = # #
  . . - = # #
  . . - = = =
  . . - - # #

 Share this Python Exercise

 More Python Programming Exercises of Managing Files

Explore our set of Python Programming Exercises! Specifically designed for beginners, these exercises will help you develop a solid understanding of the basics of Python. From variables and data types to control structures and simple functions, each exercise is crafted to challenge you incrementally as you build confidence in coding in Python.

  •  Console BMP Viewer V2

    In this exercise, you will develop a Python program to create a utility that displays a 72x24 BMP file on the console. This exercise is perfect for practicing ...

  •  Saving Data to a Text File

    In this exercise, you will develop a Python program to collect multiple sentences from the user (continuing until the user presses Enter without typing anything) and ...

  •  Adding Content to a Text File

    In this exercise, you will develop a Python program that prompts the user to input multiple sentences, stopping when they press Enter without typing anything. This ...

  •  Show File Data

    In this exercise, you will develop a Python program to read and display the contents of a text file. This exercise is perfect for practicing file handling, com...

  •  TextToHTML with File Integration

    In this exercise, you will develop a Python program to enhance the TextToHTML class by adding the ability to save its results into a text file. This exercise i...

  •  Log Handler

    In this exercise, you will develop a Python program with a class called Logger, which includes a static method called log. This exercise is perfect for practic...