kaiser-data commited on
Commit
2a39f76
·
verified ·
1 Parent(s): e033791

Upload 7 files

Browse files
Files changed (7) hide show
  1. Dockerfile +24 -0
  2. README.md +241 -0
  3. README_HF.md +34 -0
  4. packages.txt +2 -0
  5. qr_generator.py +389 -0
  6. requirements.txt +3 -0
  7. screenshot.png +0 -0
Dockerfile ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use Python 3.11 slim image
2
+ FROM python:3.11-slim
3
+
4
+ # Set working directory
5
+ WORKDIR /app
6
+
7
+ # Copy requirements first (for better caching)
8
+ COPY requirements.txt .
9
+
10
+ # Install dependencies
11
+ RUN pip install --no-cache-dir -r requirements.txt
12
+
13
+ # Copy application files
14
+ COPY qr_generator.py .
15
+
16
+ # Expose Streamlit port
17
+ EXPOSE 7860
18
+
19
+ # Set environment variable for Streamlit
20
+ ENV STREAMLIT_SERVER_PORT=7860
21
+ ENV STREAMLIT_SERVER_ADDRESS=0.0.0.0
22
+
23
+ # Run the app
24
+ CMD ["streamlit", "run", "qr_generator.py", "--server.port=7860", "--server.address=0.0.0.0"]
README.md ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 📱 QR Code Generator
2
+
3
+ **Free & Open Source** • **No Ads** • **Privacy-Friendly**
4
+
5
+ A beautiful, easy-to-use QR code generator built with Streamlit. Create custom QR codes with various styles, colors, and logos - all in your browser, completely free!
6
+
7
+ ![QR Code Generator Screenshot](screenshot.png)
8
+
9
+ ---
10
+
11
+ ## ✨ Features
12
+
13
+ ### 🚀 **Quick Start Templates**
14
+ - **URL** - Website links and landing pages
15
+ - **WiFi** - Share WiFi credentials instantly
16
+ - **Email** - mailto links with pre-filled subject/body
17
+ - **Phone** - Click-to-call phone numbers
18
+ - **Text** - Any plain text message
19
+
20
+ ### 🎨 **Customization Options**
21
+ - **Colors** - Custom foreground and background colors
22
+ - **Shapes** - Square, Rounded, Circle, Gapped Square modules
23
+ - **Resolution** - Adjustable size (5-30 pixels per module)
24
+ - **Error Correction** - 4 levels (Low, Medium, High, Very High)
25
+ - **Logo Integration** - Add your logo to the center of QR codes
26
+
27
+ ### 🛡️ **Privacy First**
28
+ - ✅ No data collection
29
+ - ✅ No tracking or analytics
30
+ - ✅ Everything runs in your browser
31
+ - ✅ No registration required
32
+ - ✅ Open source code
33
+
34
+ ---
35
+
36
+ ## 🚀 Live Demo
37
+
38
+ **Try it now:** [streamlit-qrcode.streamlit.app](https://streamlit-qrcode.streamlit.app) *(update with your actual URL)*
39
+
40
+ ---
41
+
42
+ ## 💻 Run Locally
43
+
44
+ ### Prerequisites
45
+ - Python 3.7 or higher
46
+ - pip package manager
47
+
48
+ ### Installation
49
+
50
+ ```bash
51
+ # Clone the repository
52
+ git clone https://github.com/kaiser-data/streamlit-qrcode.git
53
+ cd streamlit-qrcode
54
+
55
+ # Install dependencies
56
+ pip install -r requirements.txt
57
+
58
+ # Run the app
59
+ streamlit run qr_generator.py
60
+ ```
61
+
62
+ The app will open in your browser at `http://localhost:8501`
63
+
64
+ ---
65
+
66
+ ## 🎯 Use Cases
67
+
68
+ | Use Case | Example | Description |
69
+ |----------|---------|-------------|
70
+ | **Marketing** | Product pages, promotions | Link to campaigns and track engagement |
71
+ | **Events** | Tickets, schedules | Easy access to event information |
72
+ | **WiFi Sharing** | Guest network access | Share WiFi without typing passwords |
73
+ | **Business Cards** | vCard, LinkedIn | Digital contact information |
74
+ | **Restaurants** | Menus, ordering | Contactless menu access |
75
+ | **Education** | Resources, assignments | Quick access to learning materials |
76
+
77
+ ---
78
+
79
+ ## 📖 How to Use
80
+
81
+ ### Basic Usage
82
+ 1. **Choose a template** or enter content directly
83
+ 2. **(Optional)** Customize colors, shapes, and size
84
+ 3. **Download** your QR code as PNG
85
+
86
+ ### WiFi QR Codes
87
+ 1. Click the **WiFi** template
88
+ 2. Enter your network name and password
89
+ 3. Select security type (WPA/WEP/None)
90
+ 4. Download and share!
91
+
92
+ ### Adding Logos
93
+ 1. Expand **"Customize Appearance"**
94
+ 2. Go to **Logo** tab
95
+ 3. Upload your logo (PNG recommended)
96
+ 4. Adjust logo size (keep under 30% for best scanning)
97
+ 5. Use **High** or **Very High** error correction
98
+
99
+ ---
100
+
101
+ ## 🛠️ Technical Details
102
+
103
+ ### Built With
104
+ - **[Streamlit](https://streamlit.io)** - Web framework
105
+ - **[python-qrcode](https://github.com/lincolnloop/python-qrcode)** - QR code generation
106
+ - **[Pillow](https://python-pillow.org/)** - Image processing
107
+
108
+ ### Features
109
+ - **Error Correction Levels**: L (7%), M (15%), Q (25%), H (30%)
110
+ - **Module Shapes**: Square, Rounded, Circle, Gapped Square
111
+ - **Output Format**: PNG with adjustable resolution
112
+ - **Logo Support**: Centered logo with automatic sizing
113
+
114
+ ### Supported QR Code Types
115
+ - URLs and websites
116
+ - WiFi credentials (WPA/WEP/Open)
117
+ - Email addresses (mailto links)
118
+ - Phone numbers (tel links)
119
+ - SMS messages
120
+ - Plain text
121
+ - Any custom formatted string
122
+
123
+ ---
124
+
125
+ ## 📦 Deployment
126
+
127
+ ### Streamlit Cloud (Free)
128
+
129
+ 1. **Fork this repository** or push to your GitHub account
130
+
131
+ 2. **Deploy to Streamlit Cloud:**
132
+ - Go to [share.streamlit.io](https://share.streamlit.io)
133
+ - Click "New app"
134
+ - Select your repository: `kaiser-data/streamlit-qrcode`
135
+ - Main file: `qr_generator.py`
136
+ - Click "Deploy"
137
+
138
+ 3. **Your app will be live** at a free Streamlit URL in ~2 minutes!
139
+
140
+ ### Other Platforms
141
+ - **Heroku**: Add `setup.sh` and `Procfile`
142
+ - **Docker**: Build from included `Dockerfile`
143
+ - **VPS**: Run with `streamlit run qr_generator.py --server.port 80`
144
+
145
+ ---
146
+
147
+ ## 💡 Best Practices
148
+
149
+ ### For Optimal Scanning
150
+ - ✅ Keep content short (use URL shorteners for long links)
151
+ - ✅ Use high contrast (dark on light background)
152
+ - ✅ Minimum print size: 2×2 cm (0.8×0.8 inches)
153
+ - ✅ Test QR codes before mass printing
154
+ - ✅ Use higher error correction when adding logos
155
+
156
+ ### For Logo Integration
157
+ - ✅ Use transparent PNG images
158
+ - ✅ Keep logo size under 30% of QR code
159
+ - ✅ Use "High" or "Very High" error correction
160
+ - ✅ Test scannability after adding logo
161
+ - ✅ Ensure logo doesn't obscure critical areas
162
+
163
+ ---
164
+
165
+ ## 🤝 Contributing
166
+
167
+ Contributions are welcome! Here's how you can help:
168
+
169
+ 1. **Fork the repository**
170
+ 2. **Create a feature branch** (`git checkout -b feature/AmazingFeature`)
171
+ 3. **Commit your changes** (`git commit -m 'Add some AmazingFeature'`)
172
+ 4. **Push to the branch** (`git push origin feature/AmazingFeature`)
173
+ 5. **Open a Pull Request**
174
+
175
+ ### Ideas for Contributions
176
+ - [ ] Additional QR code styles
177
+ - [ ] Batch QR code generation
178
+ - [ ] SVG export option
179
+ - [ ] QR code analytics
180
+ - [ ] More customization options
181
+ - [ ] Internationalization (i18n)
182
+
183
+ ---
184
+
185
+ ## 📄 License
186
+
187
+ This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) file for details.
188
+
189
+ ### What this means:
190
+ - ✅ Free to use for personal and commercial projects
191
+ - ✅ Modify and distribute as you like
192
+ - ✅ No warranty or liability
193
+ - ✅ Must include original license and copyright
194
+
195
+ ---
196
+
197
+ ## 🙏 Acknowledgments
198
+
199
+ - **QR Code Technology**: Invented by Denso Wave (1994)
200
+ - **Streamlit Team**: For the amazing framework
201
+ - **python-qrcode**: For the robust QR generation library
202
+ - **Community**: For feedback and contributions
203
+
204
+ ---
205
+
206
+ ## 📞 Support
207
+
208
+ - **Issues**: [GitHub Issues](https://github.com/kaiser-data/streamlit-qrcode/issues)
209
+ - **Discussions**: [GitHub Discussions](https://github.com/kaiser-data/streamlit-qrcode/discussions)
210
+ - **Star this repo** if you find it useful! ⭐
211
+
212
+ ---
213
+
214
+ ## 🔒 Privacy & Security
215
+
216
+ This app is designed with privacy in mind:
217
+
218
+ - **No data storage**: QR codes are generated in your browser and not stored
219
+ - **No tracking**: No analytics or tracking cookies
220
+ - **No server-side processing**: All processing happens client-side
221
+ - **Open source**: Full code transparency - see exactly what it does
222
+ - **No third-party services**: No external API calls or data sharing
223
+
224
+ ---
225
+
226
+ ## 📊 Project Stats
227
+
228
+ ![GitHub stars](https://img.shields.io/github/stars/kaiser-data/streamlit-qrcode?style=social)
229
+ ![GitHub forks](https://img.shields.io/github/forks/kaiser-data/streamlit-qrcode?style=social)
230
+ ![GitHub issues](https://img.shields.io/github/issues/kaiser-data/streamlit-qrcode)
231
+ ![GitHub license](https://img.shields.io/github/license/kaiser-data/streamlit-qrcode)
232
+
233
+ ---
234
+
235
+ <div align="center">
236
+
237
+ **Made with Python & Streamlit**
238
+
239
+ [Report Bug](https://github.com/kaiser-data/streamlit-qrcode/issues) • [Request Feature](https://github.com/kaiser-data/streamlit-qrcode/issues) • [View Demo](https://streamlit-qrcode.streamlit.app)
240
+
241
+ </div>
README_HF.md ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: QR Code Generator
3
+ emoji: 📱
4
+ colorFrom: green
5
+ colorTo: blue
6
+ sdk: docker
7
+ pinned: false
8
+ license: mit
9
+ ---
10
+
11
+ # 📱 QR Code Generator
12
+
13
+ **Free & Open Source** • **No Ads** • **Privacy-Friendly**
14
+
15
+ Create custom QR codes with various styles, colors, and logos - all in your browser, completely free!
16
+
17
+ ## ✨ Features
18
+
19
+ - 🚀 **Quick Start Templates** - URL, WiFi, Email, Phone, Text
20
+ - 🎨 **Full Customization** - Colors, shapes, sizes, error correction
21
+ - 🖼️ **Logo Integration** - Add your logo to QR codes
22
+ - 🛡️ **Privacy First** - No tracking, no data collection
23
+ - ⬇️ **Instant Download** - PNG format, ready to use
24
+
25
+ ## 🚀 How to Use
26
+
27
+ 1. Choose a template or enter your content
28
+ 2. (Optional) Customize appearance
29
+ 3. Download your QR code!
30
+
31
+ ## 📦 Repository
32
+
33
+ View the full source code and documentation:
34
+ 👉 [GitHub Repository](https://github.com/kaiser-data/streamlit-qrcode)
packages.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ # System packages (if needed)
2
+ # Currently empty - no system packages required
qr_generator.py ADDED
@@ -0,0 +1,389 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import qrcode
3
+ from qrcode.image.styledpil import StyledPilImage
4
+ from qrcode.image.styles.moduledrawers import (
5
+ RoundedModuleDrawer, CircleModuleDrawer,
6
+ GappedSquareModuleDrawer, SquareModuleDrawer
7
+ )
8
+ from qrcode.image.styles.colormasks import SolidFillColorMask
9
+ from PIL import Image
10
+ import io
11
+ import re
12
+
13
+ # Helper function to convert hex color to RGB tuple
14
+ def hex_to_rgb(hex_color):
15
+ """Convert hex color string to RGB tuple"""
16
+ hex_color = hex_color.lstrip('#')
17
+ return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
18
+
19
+ # Page configuration
20
+ st.set_page_config(
21
+ page_title="QR Code Generator",
22
+ page_icon="📱",
23
+ layout="centered",
24
+ initial_sidebar_state="collapsed"
25
+ )
26
+
27
+ # Custom CSS for better UX
28
+ st.markdown("""
29
+ <style>
30
+ .big-input textarea {
31
+ font-size: 18px !important;
32
+ }
33
+ .template-button {
34
+ text-align: center;
35
+ padding: 10px;
36
+ border-radius: 8px;
37
+ cursor: pointer;
38
+ }
39
+ .stDownloadButton button {
40
+ width: 100%;
41
+ background-color: #4CAF50;
42
+ color: white;
43
+ font-size: 18px;
44
+ padding: 12px;
45
+ border-radius: 8px;
46
+ }
47
+ </style>
48
+ """, unsafe_allow_html=True)
49
+
50
+ # Initialize session state
51
+ if 'qr_data' not in st.session_state:
52
+ st.session_state.qr_data = "https://streamlit.io"
53
+ if 'template_type' not in st.session_state:
54
+ st.session_state.template_type = "url"
55
+ if 'show_advanced' not in st.session_state:
56
+ st.session_state.show_advanced = False
57
+
58
+ # Header
59
+ st.title("📱 QR Code Generator")
60
+ st.markdown("**Free & Open Source** • No Ads • Privacy-Friendly")
61
+
62
+ # ============ TEMPLATES (QUICK START) ============
63
+ st.markdown("### 🚀 Quick Start Templates")
64
+
65
+ templates = [
66
+ ("URL", "🌐", "url", "https://example.com"),
67
+ ("WiFi", "📶", "wifi", ""),
68
+ ("Email", "📧", "email", "mailto:[email protected]"),
69
+ ("Phone", "📞", "phone", "tel:+1234567890"),
70
+ ("Text", "💬", "text", "Hello World!")
71
+ ]
72
+
73
+ # Create responsive grid layout (3 columns on first row, 2 on second)
74
+ col1, col2, col3 = st.columns(3)
75
+ cols = [col1, col2, col3]
76
+
77
+ for idx, (name, icon, template_id, placeholder) in enumerate(templates[:3]):
78
+ with cols[idx]:
79
+ if st.button(f"{icon}\n{name}", use_container_width=True, key=f"btn_{template_id}"):
80
+ st.session_state.template_type = template_id
81
+ if template_id == "wifi":
82
+ st.session_state.qr_data = ""
83
+ else:
84
+ st.session_state.qr_data = placeholder
85
+ st.rerun()
86
+
87
+ col4, col5, col6 = st.columns(3)
88
+ cols2 = [col4, col5, col6]
89
+
90
+ for idx, (name, icon, template_id, placeholder) in enumerate(templates[3:]):
91
+ with cols2[idx]:
92
+ if st.button(f"{icon}\n{name}", use_container_width=True, key=f"btn_{template_id}"):
93
+ st.session_state.template_type = template_id
94
+ if template_id == "wifi":
95
+ st.session_state.qr_data = ""
96
+ else:
97
+ st.session_state.qr_data = placeholder
98
+ st.rerun()
99
+
100
+ # ============ SMART INPUT AREA ============
101
+ st.markdown("---")
102
+
103
+ # Template-specific input
104
+ if st.session_state.template_type == "wifi":
105
+ st.markdown("### 📶 WiFi Configuration")
106
+ col1, col2 = st.columns(2)
107
+ with col1:
108
+ wifi_ssid = st.text_input("Network Name (SSID)", placeholder="MyWiFi")
109
+ wifi_password = st.text_input("Password", type="password", placeholder="password123")
110
+ with col2:
111
+ wifi_security = st.selectbox("Security Type", ["WPA", "WEP", "nopass"], index=0)
112
+ wifi_hidden = st.checkbox("Hidden Network", value=False)
113
+
114
+ # Generate WiFi QR format
115
+ if wifi_ssid:
116
+ hidden_str = "true" if wifi_hidden else "false"
117
+ if wifi_security == "nopass":
118
+ qr_data = f"WIFI:T:{wifi_security};S:{wifi_ssid};H:{hidden_str};;"
119
+ else:
120
+ qr_data = f"WIFI:T:{wifi_security};S:{wifi_ssid};P:{wifi_password};H:{hidden_str};;"
121
+ else:
122
+ qr_data = ""
123
+ else:
124
+ # Standard input for all other types
125
+ input_labels = {
126
+ "url": "🌐 Enter your URL or website",
127
+ "email": "📧 Enter email address or mailto link",
128
+ "phone": "📞 Enter phone number",
129
+ "text": "💬 Enter any text"
130
+ }
131
+
132
+ label = input_labels.get(st.session_state.template_type, "Enter your content")
133
+
134
+ qr_data = st.text_area(
135
+ label,
136
+ value=st.session_state.qr_data,
137
+ height=100,
138
+ placeholder="Type or paste your content here...",
139
+ key=f"input_{st.session_state.template_type}"
140
+ )
141
+ st.session_state.qr_data = qr_data
142
+
143
+ # Input validation and helpful feedback
144
+ validation_message = ""
145
+ validation_type = "info"
146
+
147
+ if qr_data:
148
+ # URL validation
149
+ if st.session_state.template_type == "url":
150
+ url_pattern = re.compile(r'^https?://')
151
+ if not url_pattern.match(qr_data):
152
+ validation_message = "💡 Tip: URLs should start with http:// or https://"
153
+ validation_type = "warning"
154
+
155
+ # Character count
156
+ char_count = len(qr_data)
157
+ if char_count > 2000:
158
+ validation_message = f"⚠️ Warning: {char_count} characters may result in a complex QR code"
159
+ validation_type = "warning"
160
+ elif char_count > 500:
161
+ validation_message = f"ℹ️ {char_count} characters - consider using a URL shortener for easier scanning"
162
+ validation_type = "info"
163
+
164
+ if validation_message:
165
+ if validation_type == "warning":
166
+ st.warning(validation_message)
167
+ else:
168
+ st.info(validation_message)
169
+
170
+ # ============ CUSTOMIZATION (COLLAPSED BY DEFAULT) ============
171
+ with st.expander("🎨 Customize Appearance (Optional)", expanded=False):
172
+
173
+ tab1, tab2, tab3 = st.tabs(["Colors & Style", "Size", "Logo"])
174
+
175
+ with tab1:
176
+ col1, col2 = st.columns(2)
177
+ with col1:
178
+ fill_color = st.color_picker("QR Code Color", "#000000")
179
+ module_style = st.selectbox(
180
+ "Shape Style",
181
+ options=["Square", "Rounded", "Circle", "Gapped Square"],
182
+ help="Shape of the QR code modules"
183
+ )
184
+ with col2:
185
+ back_color = st.color_picker("Background Color", "#FFFFFF")
186
+ error_correction = st.select_slider(
187
+ "Error Correction",
188
+ options=["Low", "Medium", "High", "Very High"],
189
+ value="Medium",
190
+ help="Higher levels make QR code more readable if damaged"
191
+ )
192
+
193
+ with tab2:
194
+ box_size = st.slider(
195
+ "Resolution (pixels per module)",
196
+ min_value=5,
197
+ max_value=30,
198
+ value=10,
199
+ help="Higher = larger file size but better quality"
200
+ )
201
+ border_size = st.slider(
202
+ "Border Thickness",
203
+ min_value=1,
204
+ max_value=10,
205
+ value=4
206
+ )
207
+
208
+ with tab3:
209
+ st.markdown("Add a logo or image to the center of your QR code")
210
+ logo_file = st.file_uploader(
211
+ "Upload logo",
212
+ type=["png", "jpg", "jpeg"],
213
+ help="Best results with square, transparent PNG images"
214
+ )
215
+
216
+ if logo_file:
217
+ logo_size_percent = st.slider(
218
+ "Logo size (%)",
219
+ min_value=10,
220
+ max_value=40,
221
+ value=20,
222
+ help="Logo shouldn't exceed 30% for reliable scanning"
223
+ )
224
+ else:
225
+ logo_size_percent = 20
226
+ st.info("💡 Tip: Use high error correction with logos to maintain scannability")
227
+
228
+ # ============ QR CODE GENERATION ============
229
+
230
+ # Maps
231
+ error_correction_map = {
232
+ "Low": qrcode.constants.ERROR_CORRECT_L,
233
+ "Medium": qrcode.constants.ERROR_CORRECT_M,
234
+ "High": qrcode.constants.ERROR_CORRECT_Q,
235
+ "Very High": qrcode.constants.ERROR_CORRECT_H
236
+ }
237
+
238
+ module_drawer_map = {
239
+ "Square": SquareModuleDrawer(),
240
+ "Rounded": RoundedModuleDrawer(),
241
+ "Circle": CircleModuleDrawer(),
242
+ "Gapped Square": GappedSquareModuleDrawer()
243
+ }
244
+
245
+ def generate_qr_code(data, fill, back, style, error_lvl, box, border, logo, logo_size):
246
+ """Generate QR code with given parameters"""
247
+ try:
248
+ # Convert hex colors to RGB tuples
249
+ fill_rgb = hex_to_rgb(fill)
250
+ back_rgb = hex_to_rgb(back)
251
+
252
+ qr = qrcode.QRCode(
253
+ version=1,
254
+ error_correction=error_correction_map[error_lvl],
255
+ box_size=box,
256
+ border=border,
257
+ )
258
+
259
+ qr.add_data(data)
260
+ qr.make(fit=True)
261
+
262
+ img = qr.make_image(
263
+ image_factory=StyledPilImage,
264
+ module_drawer=module_drawer_map[style],
265
+ color_mask=SolidFillColorMask(
266
+ back_color=back_rgb,
267
+ front_color=fill_rgb
268
+ )
269
+ )
270
+
271
+ # Convert to standard PIL Image for Streamlit compatibility
272
+ img = img.convert('RGB')
273
+
274
+ # Add logo if provided
275
+ if logo is not None:
276
+ logo_img = Image.open(logo)
277
+
278
+ # Calculate logo size
279
+ qr_width, qr_height = img.size
280
+ logo_max_size = min(qr_width, qr_height) * logo_size // 100
281
+
282
+ # Resize logo maintaining aspect ratio
283
+ logo_img.thumbnail((logo_max_size, logo_max_size), Image.Resampling.LANCZOS)
284
+
285
+ # Create a white background for logo if it doesn't have transparency
286
+ if logo_img.mode != 'RGBA':
287
+ logo_bg = Image.new('RGB', logo_img.size, 'white')
288
+ logo_bg.paste(logo_img, (0, 0))
289
+ logo_img = logo_bg
290
+
291
+ # Calculate position to center logo
292
+ logo_pos = (
293
+ (qr_width - logo_img.width) // 2,
294
+ (qr_height - logo_img.height) // 2
295
+ )
296
+
297
+ # Paste logo
298
+ img.paste(logo_img, logo_pos, logo_img if logo_img.mode == 'RGBA' else None)
299
+
300
+ return img, qr
301
+ except Exception as e:
302
+ st.error(f"Error generating QR code: {str(e)}")
303
+ return None, None
304
+
305
+ # ============ DISPLAY QR CODE ============
306
+ st.markdown("---")
307
+
308
+ if qr_data:
309
+ img, qr = generate_qr_code(
310
+ qr_data, fill_color, back_color, module_style,
311
+ error_correction, box_size, border_size, logo_file, logo_size_percent
312
+ )
313
+
314
+ if img:
315
+ # Display QR code
316
+ col1, col2, col3 = st.columns([1, 3, 1])
317
+ with col2:
318
+ st.image(img, use_container_width=True)
319
+
320
+ # Download button (prominent)
321
+ buf = io.BytesIO()
322
+ img.save(buf, format="PNG")
323
+ byte_im = buf.getvalue()
324
+
325
+ st.download_button(
326
+ label="⬇️ Download QR Code",
327
+ data=byte_im,
328
+ file_name="qr_code.png",
329
+ mime="image/png",
330
+ use_container_width=True
331
+ )
332
+
333
+ # QR Code info
334
+ col1, col2, col3 = st.columns(3)
335
+ with col1:
336
+ st.metric("Size", f"{img.size[0]}×{img.size[1]}px")
337
+ with col2:
338
+ st.metric("Version", qr.version)
339
+ with col3:
340
+ st.metric("Characters", len(qr_data))
341
+
342
+ else:
343
+ # Show helpful message when empty
344
+ st.info("👆 Enter content above or select a template to generate your QR code")
345
+
346
+ # Show example QR code
347
+ example_img, _ = generate_qr_code(
348
+ "https://streamlit.io",
349
+ "#000000", "#FFFFFF", "Square", "Medium", 10, 4, None, 20
350
+ )
351
+ if example_img:
352
+ col1, col2, col3 = st.columns([1, 2, 1])
353
+ with col2:
354
+ st.image(example_img, caption="Example QR Code", use_container_width=True)
355
+
356
+ # ============ HELPFUL TIPS ============
357
+ with st.expander("ℹ️ Tips & Examples"):
358
+ st.markdown("""
359
+ ### 📝 Format Examples:
360
+
361
+ **Website/URL:**
362
+ - `https://www.example.com`
363
+ - `https://mysite.com/page?id=123`
364
+
365
+ **Email:**
366
+ - `mailto:[email protected]`
367
+ - `mailto:[email protected]?subject=Hello&body=Message`
368
+
369
+ **Phone:**
370
+ - `tel:+1234567890`
371
+
372
+ **SMS:**
373
+ - `sms:+1234567890`
374
+ - `sms:+1234567890?body=Hello there`
375
+
376
+ **WiFi** (use WiFi template):
377
+ - Automatically formatted when you fill the form
378
+
379
+ **Plain Text:**
380
+ - Any text you want to encode
381
+
382
+ ### 💡 Best Practices:
383
+ - Keep content short for easier scanning
384
+ - Use URL shorteners for long links
385
+ - Test QR codes before printing
386
+ - Use high error correction if adding logos
387
+ - Ensure good contrast (dark on light background)
388
+ - Maintain minimum size (2×2 cm for print)
389
+ """)
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ streamlit>=1.28.0
2
+ qrcode[pil]>=7.4.2
3
+ Pillow>=10.0.0
screenshot.png ADDED