Last active
March 19, 2025 19:05
-
-
Save laplante-sean/a8d59812140119d175ea16bb8ec1a03a to your computer and use it in GitHub Desktop.
Binary to image visualizer
This file contains hidden or 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
""" | |
Visualize any binary file as an RGB image. | |
Dependencies: numpy, pillow | |
""" | |
import os | |
import sys | |
import math | |
import hashlib | |
import argparse | |
import traceback | |
from PIL import Image, ImageFont, ImageDraw | |
import numpy as np | |
def main() -> int: | |
"""Entry Point.""" | |
parser = argparse.ArgumentParser(description="Make an image from a binary...or any file") | |
parser.add_argument("-f", "--file", help="Path to file", required=True) | |
parser.add_argument("-o", "--output", help="Path to output file", required=True) | |
parser.add_argument("--force", help="Overwrite output file if it exists", action="store_true") | |
args = parser.parse_args() | |
in_file = args.file | |
out_file = args.output | |
if not os.path.exists(in_file): | |
print(f"File {in_file} does not exist.") | |
return 1 | |
if os.path.exists(out_file) and not args.force: | |
print(f"Output file already exists. Use --force to overwrite.") | |
return 1 | |
file_bytes = None | |
with open(in_file, "rb") as fh: | |
file_bytes = fh.read() | |
# For now just RGB | |
num_pixels = math.ceil(len(file_bytes) / 3) | |
width = math.ceil(math.sqrt(num_pixels)) | |
file_hash = hashlib.sha256(file_bytes).hexdigest() | |
print(f"Hash: {file_hash}") | |
print(f"Length of file: {len(file_bytes)}") | |
print(f"Num pixels: {num_pixels}") | |
print(f"Resolution: {width}x{width}") | |
array = np.zeros((width, width, 3), dtype=np.uint8) | |
idx = 0 | |
row = 0 | |
col = 0 | |
for _ in range(num_pixels): | |
if idx + 2 >= len(file_bytes): | |
break | |
r = file_bytes[idx] | |
g = file_bytes[idx + 1] | |
b = file_bytes[idx + 2] | |
idx += 3 | |
array[row][col] = [r, g, b] | |
col += 1 | |
if col == width: | |
col = 0 | |
row += 1 | |
img_text = f"{os.path.basename(in_file)}\n{file_hash}" | |
im = Image.fromarray(array, mode="RGB") | |
draw = ImageDraw.Draw(im) | |
font = ImageFont.load_default(size=32) | |
left, top, right, bottom = draw.textbbox((0, 0), img_text, font=font) | |
draw.rectangle((left - 5, top - 5, right + 5, bottom + 5), fill="white") | |
draw.text((0, 0), img_text, font=font, fill="black") | |
im.save(out_file) | |
return 0 | |
if __name__ == "__main__": | |
rc = 1 | |
try: | |
rc = main() | |
except Exception as exc: | |
traceback.print_exc() | |
sys.exit(rc) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
first