Exercise
Console BMP Viewer V2
Objective
Develop a Python program to create a utility that displays a 72x24 BMP file on the console. Use the information in the BMP header (refer to the exercise of Feb. 7th). Pay attention to the field named "start of image data". After that position, you will find the pixels of the image. You can ignore the information about the color palette and draw an "X" when the color is 255, and a blank space if the color is different.
Note: You can create a test image with the following steps on Paint for Windows: Open Paint, create a new image, change its properties in the File menu so that it is a color image, width 72, height 24, and save as "256 color bitmap (BMP)".
Example Python Exercise
Show Python Code
import sys
def read_bmp_header(filename):
"""
Reads the BMP header and validates that it is a 72x24 BMP file.
Returns the start of image data and the dimensions.
"""
try:
with open(filename, "rb") as file:
# Check the BMP signature (first two bytes should be 'BM')
signature = file.read(2)
if signature != b'BM':
raise ValueError("The file is not a valid BMP file.")
# Skip to width and height in the BMP header
file.seek(18)
width = int.from_bytes(file.read(4), byteorder='little')
height = int.from_bytes(file.read(4), byteorder='little')
if width != 72 or height != 24:
raise ValueError("This program only supports BMP files with dimensions 72x24.")
# Skip to the start of image data
file.seek(10)
start_of_data = int.from_bytes(file.read(4), byteorder='little')
return start_of_data, width, height
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 read_bmp_data(filename, start_of_data, width, height):
"""
Reads the image data from the BMP file starting at the specified position.
Returns the pixel data as a 2D list.
"""
try:
with open(filename, "rb") as file:
# Go to the start of the image data
file.seek(start_of_data)
# Read the image data into a 2D list
pixels = []
row_size = (width + 3) // 4 * 4 # Each row must be a multiple of 4 bytes
for _ in range(height):
row = list(file.read(row_size))[:width]
pixels.append(row)
return pixels[::-1] # BMP stores rows bottom-to-top
except Exception as e:
print(f"Error while reading image data: {str(e)}")
sys.exit(1)
def display_bmp_image(pixels):
"""
Displays the BMP image on the console using 'X' for 255 and ' ' for other values.
"""
for row in pixels:
line = ''.join('X' if pixel == 255 else ' ' for pixel in row)
print(line)
if __name__ == "__main__":
# Ensure the filename is provided as a command-line argument
if len(sys.argv) != 2:
print("Usage: python bmp_viewer.py ")
sys.exit(1)
filename = sys.argv[1]
# Read BMP header
start_of_data, width, height = read_bmp_header(filename)
# Read BMP image data
pixels = read_bmp_data(filename, start_of_data, width, height)
# Display the image
display_bmp_image(pixels)
Output
Execution:
python bmp_viewer.py example.bmp
Output:
X X X X X X
X X X X X X
X X X X X X
X X X X X X
...
Share this Python Exercise