# converter.py import sys import os import argparse from PIL import Image # Requires Pillow (pip install pillow) from tqdm import tqdm # For the progress bar (pip install tqdm) import codec def human_readable_size(size, decimal_places=2): """ Convert a size in bytes to a human readable format. """ for unit in ['B','KB','MB','GB','TB']: if size < 1024: return f"{size:.{decimal_places}f} {unit}" size /= 1024 def png_to_simimg(png_path, output_path, use_transparency): """ Loads a PNG file, converts it to a 2D pixel list (RGB or RGBA based on transparency setting), and encodes it to our custom SIMIMG format. Also displays a progress bar during conversion and prints original/new file sizes and compression ratio. Args: png_path: Input PNG filename. output_path: Output SIMIMG filename. use_transparency (bool): If True, converts image to RGBA (retaining transparency); if False, converts to RGB. """ # Get and show the original PNG file size. orig_size = os.path.getsize(png_path) print(f"Original PNG size: {human_readable_size(orig_size)}") with Image.open(png_path) as img: # Convert based on transparency flag. if use_transparency: img = img.convert("RGBA") else: img = img.convert("RGB") width, height = img.size pixels = list(img.getdata()) # Convert flat pixel list to a 2D list (row-major order) with a progress bar. image_pixels = [] for i in tqdm(range(height), desc="Converting rows", unit="row"): row = pixels[i * width:(i + 1) * width] image_pixels.append(row) # Encode the image into our custom SIMIMG format. simimg_data = codec.encode(image_pixels) # Write the SIMIMG file. with open(output_path, "wb") as f: f.write(simimg_data) # Get the new file size. new_size = os.path.getsize(output_path) print(f"Converted SIMIMG size: {human_readable_size(new_size)}") # Calculate and display the compression ratio. # (Note: Ratio as new_size/orig_size. Values below 1.0 indicate compression.) compression_ratio = new_size / orig_size print(f"Compression Ratio: {compression_ratio:.2f}") if __name__ == '__main__': parser = argparse.ArgumentParser( description="Convert a PNG image to the custom SIMIMG format." ) parser.add_argument("input", help="Input PNG file.") parser.add_argument("output", help="Output SIMIMG file.") parser.add_argument( "--transparency", action="store_true", help="Convert image with transparency (RGBA); otherwise use RGB." ) args = parser.parse_args() png_to_simimg(args.input, args.output, use_transparency=args.transparency)