import qrcode
from PIL import Image
import gradio as gr
import io
import base64
import numpy as np
import cv2
import tempfile
# Function to generate a QR code and return Base64 and PNG file
def generate_qr(data):
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
qr.add_data(data)
qr.make(fit=True)
img = qr.make_image(fill="black", back_color="white")
# Encode the image as a base64 string
buffered = io.BytesIO()
img.save(buffered, format="PNG")
img_base64 = base64.b64encode(buffered.getvalue()).decode("utf-8")
# Save the image temporarily as a PNG file
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
img.save(temp_file.name, format="PNG")
temp_file.close()
return f"data:image/png;base64,{img_base64}", temp_file.name, img_base64
# Function to decode a QR code from an uploaded image
def decode_qr(img):
if img is None:
return "No image uploaded."
# Convert PIL image to a NumPy array
img_array = np.array(img)
# Convert RGB to BGR as OpenCV expects
if img_array.ndim == 3:
img_array = cv2.cvtColor(img_array, cv2.COLOR_RGB2BGR)
# Initialize OpenCV QR code detector
detector = cv2.QRCodeDetector()
data, _, _ = detector.detectAndDecode(img_array)
return data if data else "No QR code found."
# Gradio Interface
def create_gradio_interface():
with gr.Blocks() as demo:
gr.Markdown("## QR Code Generator and Decoder")
# Tab for generating QR codes
with gr.Tab("Generate QR Code"):
with gr.Row():
data_input = gr.Textbox(placeholder="Enter text or URL to encode", label="Input Data")
generate_button = gr.Button("Generate QR Code")
qr_code_html = gr.HTML(label="Generated QR Code (Base64 Embedded)")
qr_png_file = gr.File(label="Download QR Code (PNG)")
qr_base64_file = gr.File(label="Download Base64 (TXT)")
def generate_qr_interface(data):
if not data.strip():
raise ValueError("Input text cannot be empty!")
img_base64, png_path, base64_str = generate_qr(data)
# Save Base64 string as a .txt file
base64_txt_path = tempfile.NamedTemporaryFile(delete=False, suffix=".txt")
with open(base64_txt_path.name, "w") as f:
f.write(base64_str)
# Wrap the base64 string in an tag for display
html_content = f''
return html_content, png_path, base64_txt_path.name
generate_button.click(
generate_qr_interface,
inputs=data_input,
outputs=[qr_code_html, qr_png_file, qr_base64_file],
)
# Tab for decoding QR codes
with gr.Tab("Decode QR Code"):
with gr.Row():
image_input = gr.Image(type="pil", label="Upload QR Code Image")
decode_button = gr.Button("Decode QR Code")
decoded_text = gr.Textbox(label="Decoded Text", interactive=True)
decode_button.click(
decode_qr,
inputs=image_input,
outputs=decoded_text,
)
demo.launch(share=True)
# Run the Gradio interface
create_gradio_interface()