Created
June 2, 2023 14:08
-
-
Save DevStefIt/36b99717ed1effc3ce2ef5c323c77b94 to your computer and use it in GitHub Desktop.
BMP File Format programs used in the video
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
from PIL import Image | |
def create_random_image(width, height): | |
# Create a new blank image with RGB mode | |
image = Image.new('RGB', (width, height)) | |
# Create a pixel map | |
pixels = image.load() | |
for y in range(height): | |
for x in range(width): | |
r = random.randint(0, 255) | |
g = random.randint(0, 255) | |
b = random.randint(0, 255) | |
pixels[x, y] = (r, g, b) | |
return image | |
width = 8 | |
height = 8 | |
image = create_random_image(width, height) | |
image.save('random_image.bmp') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from tkinter import Tk | |
from tkinter.filedialog import askopenfilename | |
from pathlib import Path | |
def parse_bmp(file_path): | |
with open(file_path, 'rb') as f: | |
# Read BMP header | |
signature = f.read(2).decode('ascii') | |
file_size = int.from_bytes(f.read(4), 'little') | |
reserved_1 = int.from_bytes(f.read(2), 'little') | |
reserved_2 = int.from_bytes(f.read(2), 'little') | |
pixel_data_offset = int.from_bytes(f.read(4), 'little') | |
# Read DIB header | |
dib_header_size = int.from_bytes(f.read(4), 'little') | |
width = int.from_bytes(f.read(4), 'little', signed=True) | |
height = int.from_bytes(f.read(4), 'little', signed=True) | |
color_planes = int.from_bytes(f.read(2), 'little') | |
bit_depth = int.from_bytes(f.read(2), 'little') | |
compression_method = int.from_bytes(f.read(4), 'little') | |
image_size = int.from_bytes(f.read(4), 'little') | |
horizontal_resolution = int.from_bytes(f.read(4), 'little') | |
vertical_resolution = int.from_bytes(f.read(4), 'little') | |
colors_in_palette = int.from_bytes(f.read(4), 'little') | |
important_colors = int.from_bytes(f.read(4), 'little') | |
# Process pixel data | |
f.seek(pixel_data_offset) | |
# Calculate row padding | |
row_size = ((bit_depth * width + 31) // 32) * 4 | |
padding = row_size - ((bit_depth * width) // 8) | |
pixel_data = [] | |
for _ in range(abs(height)): | |
row = [] | |
for _ in range(width): | |
if bit_depth == 24: | |
blue = ord(f.read(1)) | |
green = ord(f.read(1)) | |
red = ord(f.read(1)) | |
row.append((red, green, blue)) | |
elif bit_depth == 32: | |
blue = ord(f.read(1)) | |
green = ord(f.read(1)) | |
red = ord(f.read(1)) | |
alpha = ord(f.read(1)) | |
row.append((red, green, blue, alpha)) | |
else: | |
raise ValueError("Unsupported bit depth") | |
f.read(padding) # Skip padding bytes | |
pixel_data.append(row) | |
# Create list of field information | |
bmp_info = [ | |
('Signature', 0, 2, signature.encode('ascii').hex(), signature), | |
('File Size', 2, 4, chr(file_size), file_size), | |
('Reserved 1', 6, 2, hex(reserved_1), reserved_1), | |
('Reserved 2', 8, 2, hex(reserved_2), reserved_2), | |
('Pixel Data Offset', 10, 4, hex(pixel_data_offset), pixel_data_offset), | |
('DIB Header Size', 14, 4, hex(dib_header_size), dib_header_size), | |
('Width', 18, 4, hex(width), width), | |
('Height', 22, 4, hex(height), height), | |
('Color Planes', 26, 2, hex(color_planes), color_planes), | |
('Bit Depth', 28, 2, hex(bit_depth), bit_depth), | |
('Compression Method', 30, 4, hex(compression_method), compression_method), | |
('Image Size', 34, 4, hex(image_size), image_size), | |
('Horizontal Resolution', 38, 4, hex(horizontal_resolution), horizontal_resolution), | |
('Vertical Resolution', 42, 4, hex(vertical_resolution), vertical_resolution), | |
('Colors in Palette', 46, 4, hex(colors_in_palette), colors_in_palette), | |
('Important Colors', 50, 4, hex(important_colors), important_colors) | |
] | |
# Print field information as tab-separated values | |
print("field_name,offset,size,value,hex") | |
for field_info in bmp_info: | |
field_name, offset, size, hex_value, value = field_info | |
if isinstance(value, str): | |
hex_value = ' '.join(f"{byte:02X}" for byte in value.encode()) | |
else: | |
hex_value = ' '.join(f"{byte:02X}" for byte in value.to_bytes(size, 'little')) | |
print(f"{field_name},{hex(offset)},{size},{value},{hex_value}") | |
return pixel_data | |
root=Tk() | |
root.withdraw() | |
bmp_file_path = Path(askopenfilename(title='Select a bitmap file', initialdir='bmp_parser', filetypes=[('Bitmap files', '*.bmp'),('All files', '*.*')])) # shows dialog box and return the path | |
bmp_info = parse_bmp(bmp_file_path) | |
#print(f"Pixel Data: {pixel_data}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
field_name | offset | size | value | hex | |
---|---|---|---|---|---|
Signature | 0x0 | 2 | BM | 42 4D | |
File Size | 0x2 | 4 | 246 | F6 00 00 00 | |
Reserved 1 | 0x6 | 2 | 0 | 00 00 | |
Reserved 2 | 0x8 | 2 | 0 | 00 00 | |
Pixel Data Offset | 0xa | 4 | 54 | 36 00 00 00 | |
DIB Header Size | 0xe | 4 | 40 | 28 00 00 00 | |
Width | 0x12 | 4 | 8 | 08 00 00 00 | |
Height | 0x16 | 4 | 8 | 08 00 00 00 | |
Color Planes | 0x1a | 2 | 1 | 01 00 | |
Bit Depth | 0x1c | 2 | 24 | 18 00 | |
Compression Method | 0x1e | 4 | 0 | 00 00 00 00 | |
Image Size | 0x22 | 4 | 192 | C0 00 00 00 | |
Horizontal Resolution | 0x26 | 4 | 3780 | C4 0E 00 00 | |
Vertical Resolution | 0x2a | 4 | 3780 | C4 0E 00 00 | |
Colors in Palette | 0x2e | 4 | 0 | 00 00 00 00 | |
Important Colors | 0x32 | 4 | 0 | 00 00 00 00 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment