80 lines
2.8 KiB
Python
80 lines
2.8 KiB
Python
# 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)
|