|
from PIL import Image, ImageColor |
|
import os, zipfile, tempfile, shutil |
|
|
|
def recolor_icons(zip_file, hex_color): |
|
target_rgb = ImageColor.getrgb(hex_color) |
|
|
|
|
|
|
|
|
|
temp_input_dir = tempfile.mkdtemp() |
|
temp_output_zip = tempfile.NamedTemporaryFile(delete=False, suffix=".zip") |
|
temp_output_zip.close() |
|
|
|
try: |
|
|
|
with zipfile.ZipFile(zip_file, 'r') as zip_ref: |
|
zip_ref.extractall(temp_input_dir) |
|
|
|
|
|
for root, _, files in os.walk(temp_input_dir): |
|
for filename in files: |
|
if filename.lower().endswith('.png'): |
|
filepath = os.path.join(root, filename) |
|
image = Image.open(filepath).convert("RGBA") |
|
pixels = image.load() |
|
|
|
for y in range(image.height): |
|
for x in range(image.width): |
|
r, g, b, a = pixels[x, y] |
|
if a != 0: |
|
pixels[x, y] = (*target_rgb, a) |
|
|
|
image.save(filepath) |
|
|
|
|
|
with zipfile.ZipFile(temp_output_zip.name, 'w') as zip_out: |
|
for root, _, files in os.walk(temp_input_dir): |
|
for file in files: |
|
full_path = os.path.join(root, file) |
|
arcname = os.path.relpath(full_path, temp_input_dir) |
|
zip_out.write(full_path, arcname) |
|
|
|
return temp_output_zip.name |
|
|
|
finally: |
|
shutil.rmtree(temp_input_dir) |
|
|
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown("## π¨ PNG Recoloring Tool") |
|
gr.Markdown( |
|
"Upload a **ZIP** file of `.png` icons and choose a color to apply to all visible pixels.\n" |
|
"Transparency is preserved β only the visible parts are recolored." |
|
) |
|
|
|
with gr.Row(): |
|
zip_input = gr.File(label="π Upload ZIP of PNGs", file_types=[".zip"]) |
|
color_picker = gr.ColorPicker(label="π¨ Choose Color", value="#ffffff") |
|
|
|
output_zip = gr.File(label="β¬οΈ Download Recolored ZIP") |
|
|
|
submit_btn = gr.Button("π Recolor Icons") |
|
|
|
submit_btn.click(fn=recolor_icons, inputs=[zip_input, color_picker], outputs=output_zip) |
|
|
|
if __name__ == "__main__": |
|
demo.launch() |