| import gradio as gr |
| import qrcode |
| from PIL import Image |
| import uuid |
| import re |
|
|
| |
| def rgba_to_hex(rgba): |
| if rgba.startswith("#"): |
| return rgba |
| match = re.findall(r"[\d.]+", rgba) |
| r, g, b = [int(float(x)) for x in match[:3]] |
| return "#{:02X}{:02X}{:02X}".format(r, g, b) |
|
|
| def generate_qr(data, fg_color, bg_color, logo): |
| if not data: |
| raise gr.Error("Please enter text or URL!") |
|
|
| |
| fg_color = rgba_to_hex(fg_color) |
| bg_color = rgba_to_hex(bg_color) |
|
|
| |
| if fg_color.lower() == bg_color.lower(): |
| fg_color = "#000000" |
| bg_color = "#FFFFFF" |
|
|
| |
| qr = qrcode.QRCode( |
| version=8, |
| box_size=10, |
| border=4, |
| error_correction=qrcode.constants.ERROR_CORRECT_H |
| ) |
|
|
| qr.add_data(data) |
| qr.make(fit=True) |
|
|
| img = qr.make_image(fill_color=fg_color, back_color=bg_color).convert("RGB") |
|
|
| |
| if logo: |
| logo_img = Image.open(logo).convert("RGBA") |
|
|
| qr_w, qr_h = img.size |
|
|
| |
| logo_size = int(qr_w * 0.12) |
| logo_img = logo_img.resize((logo_size, logo_size)) |
|
|
| |
| border = 20 |
| box_w = logo_size + border |
| box_h = logo_size + border |
| white_box = Image.new("RGB", (box_w, box_h), "white") |
|
|
| |
| pos = ((qr_w - box_w)//2, (qr_h - box_h)//2) |
| img.paste(white_box, pos) |
|
|
| |
| img.paste(logo_img, (pos[0] + border//2, pos[1] + border//2), mask=logo_img) |
|
|
| return img |
|
|
|
|
| def save_qr(data, fg_color, bg_color, logo): |
| img = generate_qr(data, fg_color, bg_color, logo) |
| filepath = f"/tmp/qr_{uuid.uuid4().hex}.png" |
| img.save(filepath) |
| return filepath |
|
|
|
|
| with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue")) as demo: |
| gr.Markdown("## β SCANNABLE QR Code Generator (Safe Logo + Colors)") |
|
|
| text = gr.Textbox(label="Enter Text / URL") |
|
|
| with gr.Row(): |
| fg_color = gr.ColorPicker(label="Foreground", value="#000000") |
| bg_color = gr.ColorPicker(label="Background", value="#FFFFFF") |
|
|
| logo = gr.Image(label="Upload Logo (optional)", type="filepath") |
|
|
| with gr.Row(): |
| generate = gr.Button("Generate") |
| download = gr.Button("Download") |
|
|
| output = gr.Image(label="QR Code Preview") |
|
|
| generate.click(generate_qr, [text, fg_color, bg_color, logo], output) |
| download.click(save_qr, [text, fg_color, bg_color, logo], gr.File()) |
|
|
| demo.launch() |
|
|