first commit
This commit is contained in:
182
convert_icon.py
Normal file
182
convert_icon.py
Normal file
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Icon Converter Utility
|
||||
Converts PNG images to ICO format for Windows applications
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
from PIL import Image, ImageDraw
|
||||
except ImportError:
|
||||
print("Pillow is required for image conversion. Installing...")
|
||||
import subprocess
|
||||
subprocess.check_call([sys.executable, "-m", "pip", "install", "Pillow"])
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
|
||||
def create_default_icon():
|
||||
"""Create a default LLM_Train icon if no PNG is provided."""
|
||||
# Create a 256x256 icon with gradient background
|
||||
size = 256
|
||||
image = Image.new('RGBA', (size, size), (0, 0, 0, 0))
|
||||
draw = ImageDraw.Draw(image)
|
||||
|
||||
# Create gradient background
|
||||
for i in range(size):
|
||||
alpha = int(255 * (i / size))
|
||||
color = (45, 85, 135, alpha) # Blue gradient
|
||||
draw.line([(0, i), (size, i)], fill=color)
|
||||
|
||||
# Draw "LLM" text-like representation
|
||||
center = size // 2
|
||||
|
||||
# Draw stylized "LLM" using rectangles
|
||||
# L
|
||||
draw.rectangle([40, 60, 60, 180], fill=(255, 255, 255, 255))
|
||||
draw.rectangle([40, 160, 100, 180], fill=(255, 255, 255, 255))
|
||||
|
||||
# L
|
||||
draw.rectangle([110, 60, 130, 180], fill=(255, 255, 255, 255))
|
||||
draw.rectangle([110, 160, 170, 180], fill=(255, 255, 255, 255))
|
||||
|
||||
# M
|
||||
draw.rectangle([180, 60, 200, 180], fill=(255, 255, 255, 255))
|
||||
draw.rectangle([200, 60, 220, 100], fill=(255, 255, 255, 255))
|
||||
draw.rectangle([210, 100, 230, 120], fill=(255, 255, 255, 255))
|
||||
draw.rectangle([220, 120, 240, 180], fill=(255, 255, 255, 255))
|
||||
|
||||
# Add subtle border
|
||||
draw.rectangle([10, 10, size-10, size-10], outline=(255, 255, 255, 128), width=2)
|
||||
|
||||
return image
|
||||
|
||||
|
||||
def png_to_ico(png_path, ico_path=None, sizes=None):
|
||||
"""
|
||||
Convert PNG to ICO format with multiple sizes.
|
||||
|
||||
Args:
|
||||
png_path (str): Path to the input PNG file
|
||||
ico_path (str): Path for the output ICO file (optional)
|
||||
sizes (list): List of sizes to include in ICO (default: [16, 32, 48, 64, 128, 256])
|
||||
"""
|
||||
if sizes is None:
|
||||
sizes = [16, 32, 48, 64, 128, 256]
|
||||
|
||||
png_path = Path(png_path)
|
||||
|
||||
if not png_path.exists():
|
||||
print(f"PNG file not found: {png_path}")
|
||||
print("Creating default icon instead...")
|
||||
image = create_default_icon()
|
||||
else:
|
||||
try:
|
||||
image = Image.open(png_path)
|
||||
print(f"Loaded PNG: {png_path} ({image.size})")
|
||||
except Exception as e:
|
||||
print(f"Error loading PNG: {e}")
|
||||
print("Creating default icon instead...")
|
||||
image = create_default_icon()
|
||||
|
||||
# Convert to RGBA if not already
|
||||
if image.mode != 'RGBA':
|
||||
image = image.convert('RGBA')
|
||||
|
||||
# Create different sizes
|
||||
icon_images = []
|
||||
for size in sizes:
|
||||
# Resize image maintaining aspect ratio
|
||||
resized = image.resize((size, size), Image.Resampling.LANCZOS)
|
||||
icon_images.append(resized)
|
||||
print(f"Created {size}x{size} icon")
|
||||
|
||||
# Determine output path
|
||||
if ico_path is None:
|
||||
ico_path = png_path.with_suffix('.ico')
|
||||
else:
|
||||
ico_path = Path(ico_path)
|
||||
|
||||
# Save as ICO
|
||||
try:
|
||||
icon_images[0].save(
|
||||
ico_path,
|
||||
format='ICO',
|
||||
sizes=[(img.width, img.height) for img in icon_images],
|
||||
append_images=icon_images[1:]
|
||||
)
|
||||
print(f"Successfully created ICO: {ico_path}")
|
||||
return str(ico_path)
|
||||
except Exception as e:
|
||||
print(f"Error creating ICO: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def convert_assets_folder(assets_dir="assets"):
|
||||
"""Convert all PNG files in assets folder to ICO format."""
|
||||
assets_path = Path(assets_dir)
|
||||
|
||||
if not assets_path.exists():
|
||||
print(f"Assets directory not found: {assets_path}")
|
||||
return []
|
||||
|
||||
png_files = list(assets_path.glob("*.png"))
|
||||
|
||||
if not png_files:
|
||||
print(f"No PNG files found in {assets_path}")
|
||||
print("Creating default application icon...")
|
||||
|
||||
# Create default icon
|
||||
default_ico = assets_path / "llm_train.ico"
|
||||
png_to_ico("nonexistent.png", default_ico)
|
||||
return [str(default_ico)]
|
||||
|
||||
converted_files = []
|
||||
for png_file in png_files:
|
||||
ico_file = png_file.with_suffix('.ico')
|
||||
result = png_to_ico(png_file, ico_file)
|
||||
if result:
|
||||
converted_files.append(result)
|
||||
|
||||
return converted_files
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function for command line usage."""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Convert PNG images to ICO format")
|
||||
parser.add_argument("input", nargs="?", help="Input PNG file or assets directory")
|
||||
parser.add_argument("-o", "--output", help="Output ICO file")
|
||||
parser.add_argument("--sizes", nargs="+", type=int,
|
||||
default=[16, 32, 48, 64, 128, 256],
|
||||
help="Icon sizes to include")
|
||||
parser.add_argument("--assets", action="store_true",
|
||||
help="Convert all PNG files in assets directory")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.assets or not args.input:
|
||||
print("Converting assets folder...")
|
||||
converted = convert_assets_folder("assets")
|
||||
if converted:
|
||||
print(f"Converted {len(converted)} files:")
|
||||
for file in converted:
|
||||
print(f" - {file}")
|
||||
else:
|
||||
print("No files converted.")
|
||||
else:
|
||||
if Path(args.input).is_file():
|
||||
result = png_to_ico(args.input, args.output, args.sizes)
|
||||
if result:
|
||||
print(f"Conversion successful: {result}")
|
||||
else:
|
||||
print("Conversion failed.")
|
||||
else:
|
||||
print(f"Input file not found: {args.input}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user