import gradio as gr from PIL import Image from zopflipng import png_optimize import os def convert_webp(input_path, compression_level=6, lossless_mode=False): """Convert WEBP to PNG with compression options and Zopfli optimization""" try: # Convert WEBP to temporary PNG with Image.open(input_path) as img: temp_path = "temp.png" img.convert("RGB").save( temp_path, format="PNG", compress_level=compression_level, optimize=True ) # Apply ZopfliPNG optimization if enabled if lossless_mode: with open(temp_path, "rb") as f: original_data = f.read() optimized_data, code = png_optimize( original_data, num_iterations=15, lossy_8bit=False, lossy_transparent=False ) if code == 0: with open(temp_path, "wb") as f: f.write(optimized_data) else: raise RuntimeError("ZopfliPNG optimization failed") return temp_path except Exception as e: raise gr.Error(f"Conversion failed: {str(e)}") # Create Gradio interface with gr.Blocks(title="WEBP to PNG Professional Converter") as app: gr.Markdown("## 🔄 Professional WEBP to PNG Converter") with gr.Row(): with gr.Column(): input_img = gr.Image( type="filepath", label="Upload WEBP Image", height=300 ) comp_slider = gr.Slider( minimum=0, maximum=9, value=6, step=1, label="PNG Compression Level (0=fast, 9=small)", info="Standard DEFLATE compression" ) lossless_toggle = gr.Checkbox( label="Enable Professional Lossless Mode (ZopfliPNG)", info="Advanced compression (slower but smaller files)" ) convert_btn = gr.Button("Start Conversion", variant="primary") with gr.Column(): output_img = gr.Image( label="Converted PNG Result", type="filepath", height=400, interactive=False ) convert_btn.click( fn=convert_webp, inputs=[input_img, comp_slider, lossless_toggle], outputs=output_img ) if __name__ == "__main__": app.launch()