File size: 4,366 Bytes
6084325
8102829
6084325
 
 
 
5d52af1
9f0ef40
6084325
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44c3663
6084325
8102829
368d01c
24c48fb
 
 
 
 
 
 
 
8102829
 
24c48fb
8102829
6084325
 
 
 
0125c43
 
 
 
 
 
 
 
 
6084325
0125c43
6084325
 
 
44c3663
6084325
 
44c3663
 
 
 
6084325
44c3663
6084325
44c3663
 
 
 
6084325
 
0125c43
6084325
 
 
44c3663
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6084325
44c3663
6084325
44c3663
 
 
 
6084325
 
0125c43
6084325
 
 
 
 
 
 
 
 
 
 
0125c43
6084325
 
056d44f
08657ec
056d44f
0125c43
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import qrcode
import cv2
from PIL import Image
import gradio as gr
import tempfile
import os
import numpy as np

# Function to generate a QR code
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")

    # Save to a temporary file and return the file path
    temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
    img.save(temp_file.name, format="PNG")
    temp_file.close()  # Close the file to flush contents to disk
    return temp_file.name  # Return the file path

# Function to read a QR code using OpenCV
def read_qr(img):
    # Convert PIL image to a NumPy array
    img = np.array(img)

    # Convert RGB to BGR format as OpenCV expects BGR
    if img.ndim == 3:
        img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)

    # Initialize OpenCV QR code detector
    detector = cv2.QRCodeDetector()
    data, _, _ = detector.detectAndDecode(img)
    
    return data if data else "No QR code found."

# Custom CSS styling as HTML for dark mode
custom_css = """
<style>
    body {background-color: #1e1e2f; font-family: 'Arial', sans-serif; color: #e0e0e0;}
    .gradio-container {max-width: 700px; margin: auto; padding: 25px; background-color: #2c2c3e; 
                       border-radius: 15px; box-shadow: 0 8px 15px rgba(0, 0, 0, 0.3);}
    h1, h2 {text-align: center; color: #ffffff; font-weight: bold; margin-bottom: 15px;}
    .gr-button {background-color: #4a4a6a; color: #ffffff; padding: 10px 25px; border-radius: 8px; 
                font-size: 16px; border: none; transition: 0.3s;}
    .gr-button:hover {background-color: #6a6a8a; transform: scale(1.05);}
    input, textarea, .gr-box {background-color: #3a3a4f; border: 1px solid #555; border-radius: 10px; 
                              padding: 10px; font-size: 14px; color: #e0e0e0;}
    .gr-box:hover, input:hover, textarea:hover {border-color: #777;}
    .tab {margin-top: 20px;}
</style>
"""

# Add download and copy-to-clipboard functionality
def create_gradio_interface():
    # QR Code Generator Interface
    def generate_qr_with_download(data):
        qr_file = generate_qr(data)
        return qr_file, f"Download your QR code: [Download QR Code]({qr_file})"

    generate_interface = gr.Interface(
        fn=generate_qr_with_download,
        inputs=gr.Textbox(placeholder="Enter text or URL here...", label="Data to Encode"),
        outputs=[
            gr.Image(label="Generated QR Code"), 
            gr.HTML(label="Download")
        ],
        title="Generate QR Code",
        description="Quickly create a QR code from any text or URL.",
        theme="compact",
    )

    # QR Code Reader Interface
    def read_qr_with_copy(img):
        decoded_data = read_qr(img)
        clipboard_script = f"""
            <script>
                function copyToClipboard(text) {{
                    navigator.clipboard.writeText(text).then(function() {{
                        alert("Copied to clipboard: " + text);
                    }}, function(err) {{
                        alert("Failed to copy: ", err);
                    }});
                }}
            </script>
            <button onclick="copyToClipboard('{decoded_data}')">Copy to Clipboard</button>
        """
        return decoded_data, clipboard_script

    read_interface = gr.Interface(
        fn=read_qr_with_copy,
        inputs=gr.Image(type="pil", label="Upload QR Code Image"),
        outputs=[
            gr.Textbox(label="Decoded Data"), 
            gr.HTML(label="Copy to Clipboard")
        ],
        title="Read QR Code",
        description="Upload an image with a QR code to decode the embedded data.",
        theme="compact",
    )

    # Combine interfaces into a single tabbed layout
    interface = gr.TabbedInterface(
        [generate_interface, read_interface],
        ["Generate QR Code", "Read QR Code"]
    )

    # Launch interface with custom HTML for CSS styling
    with gr.Blocks() as demo:
        gr.HTML(custom_css)  # Embed the custom CSS
        gr.Markdown("# QR Code Tool\nEasily generate and decode QR codes.")
        interface.render()

    demo.launch(share=True)

# Run the Gradio interface
create_gradio_interface()