From 1ca4466e91e3d08d45a496f355352444bc83ad2f Mon Sep 17 00:00:00 2001 From: Nitesh Kumar Date: Sun, 19 Oct 2025 19:09:45 +0530 Subject: [PATCH] QR code generator and scanner CLI tool Initial commit of a command-line tool for generating and scanning QR codes. Includes Python implementation (qr_generator.py), usage instructions in README.md. --- QR-Code-Generator-Scanner/.gitignore | 67 +++++++++ QR-Code-Generator-Scanner/README.md | 52 +++++++ QR-Code-Generator-Scanner/qr_generator.py | 160 +++++++++++++++++++++ QR-Code-Generator-Scanner/requirements.txt | 3 + 4 files changed, 282 insertions(+) create mode 100644 QR-Code-Generator-Scanner/.gitignore create mode 100644 QR-Code-Generator-Scanner/README.md create mode 100644 QR-Code-Generator-Scanner/qr_generator.py create mode 100644 QR-Code-Generator-Scanner/requirements.txt diff --git a/QR-Code-Generator-Scanner/.gitignore b/QR-Code-Generator-Scanner/.gitignore new file mode 100644 index 0000000..fd3e2b8 --- /dev/null +++ b/QR-Code-Generator-Scanner/.gitignore @@ -0,0 +1,67 @@ +# QR Code Generator and Scanner - Git Ignore File + +# Generated QR code images +*.png +*.jpg +*.jpeg +*.gif +*.bmp + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# Virtual environments +venv/ +env/ +ENV/ +env.bak/ +venv.bak/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Examples directory (but keep the directory structure) +examples/*.png +examples/*.jpg +examples/*.jpeg + +# Test artifacts +.pytest_cache/ +.coverage +htmlcov/ + +# Logs +*.log diff --git a/QR-Code-Generator-Scanner/README.md b/QR-Code-Generator-Scanner/README.md new file mode 100644 index 0000000..c787b61 --- /dev/null +++ b/QR-Code-Generator-Scanner/README.md @@ -0,0 +1,52 @@ +# QR Code Generator and Reader 📱 + +Simple command-line tool to create and scan QR codes. + +## Quick Start + +1. **Install dependencies** + ```bash + pip install -r requirements.txt + ``` + +2. **Make a QR code** + ```bash + python qr_generator.py generate "Hello World!" -o hello.png + ``` + +3. **Scan a QR code** (optional - needs zbar) + ```bash + python qr_generator.py scan hello.png + ``` + +## Examples + +**Basic QR code:** +```bash +python qr_generator.py generate "Hello World!" -o hello.png +``` + +**Website link:** +```bash +python qr_generator.py generate "https://github.com" -o github.png +``` + +**Custom colors:** +```bash +python qr_generator.py generate "Colorful!" --fill-color blue --back-color yellow -o colorful.png +``` + +**WiFi sharing:** +```bash +python qr_generator.py generate "WIFI:T:WPA;S:MyNetwork;P:MyPassword;;" -o wifi.png +``` + +## Options + +- `-o, --output`: Output filename +- `-e, --error-correction`: L, M, Q, or H (default: M) +- `--fill-color`: QR code color +- `--back-color`: Background color +- `--box-size`: Size of each square +- `--border`: Border thickness + diff --git a/QR-Code-Generator-Scanner/qr_generator.py b/QR-Code-Generator-Scanner/qr_generator.py new file mode 100644 index 0000000..fd7df3a --- /dev/null +++ b/QR-Code-Generator-Scanner/qr_generator.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python3 + +import qrcode +import argparse +import sys +import os +from PIL import Image +from pyzbar import pyzbar +from typing import Optional, List + + +class QRCodeGenerator: + + def __init__(self, box_size: int = 10, border: int = 4): + self.box_size = box_size + self.border = border + + def generate_qr_code(self, data: str, error_correction: str = 'M') -> qrcode.QRCode: + error_levels = { + 'L': qrcode.constants.ERROR_CORRECT_L, + 'M': qrcode.constants.ERROR_CORRECT_M, + 'Q': qrcode.constants.ERROR_CORRECT_Q, + 'H': qrcode.constants.ERROR_CORRECT_H + } + + qr = qrcode.QRCode( + version=1, + error_correction=error_levels.get(error_correction.upper(), + qrcode.constants.ERROR_CORRECT_M), + box_size=self.box_size, + border=self.border, + ) + + qr.add_data(data) + qr.make(fit=True) + + return qr + + def save_qr_code(self, qr_code: qrcode.QRCode, filename: str, + fill_color: str = 'black', back_color: str = 'white') -> bool: + try: + img = qr_code.make_image(fill_color=fill_color, back_color=back_color) + img.save(filename) + return True + except Exception as e: + print(f"Oops! Couldn't save the QR code: {e}") + return False + + def generate_and_save(self, data: str, filename: str, + error_correction: str = 'M', + fill_color: str = 'black', + back_color: str = 'white') -> bool: + qr_code = self.generate_qr_code(data, error_correction) + return self.save_qr_code(qr_code, filename, fill_color, back_color) + + +class QRCodeScanner: + + @staticmethod + def scan_qr_code(image_path: str) -> List[str]: + try: + image = Image.open(image_path) + qr_codes = pyzbar.decode(image) + + decoded_data = [] + for qr_code in qr_codes: + data = qr_code.data.decode('utf-8') + decoded_data.append(data) + + return decoded_data + + except FileNotFoundError: + print(f"Hmm, can't find the image '{image_path}'. Double-check the path?") + return [] + except Exception as e: + print(f"Something went wrong while scanning: {e}") + return [] + + @staticmethod + def scan_and_display(image_path: str) -> None: + decoded_data = QRCodeScanner.scan_qr_code(image_path) + + if decoded_data: + print(f"Great! Found {len(decoded_data)} QR code(s) in '{image_path}':") + for i, data in enumerate(decoded_data, 1): + print(f" {i}. {data}") + else: + print(f"No QR codes found in '{image_path}'. Maybe try a different image?") + + +def main(): + parser = argparse.ArgumentParser( + description='QR Code Generator and Scanner - Make QR codes easily!', + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +Examples: + Generate QR code: + python qr_generator.py generate "Hello, World!" -o hello.png + python qr_generator.py generate "https://github.com" -o github.png -e H + + Scan QR code: + python qr_generator.py scan hello.png + """ + ) + + subparsers = parser.add_subparsers(dest='command', help='What do you want to do?') + + generate_parser = subparsers.add_parser('generate', help='Create a QR code') + generate_parser.add_argument('data', help='What text or URL to put in the QR code') + generate_parser.add_argument('-o', '--output', default='qrcode.png', + help='Where to save it (default: qrcode.png)') + generate_parser.add_argument('-e', '--error-correction', + choices=['L', 'M', 'Q', 'H'], default='M', + help='How much error correction? L=low, M=medium, Q=good, H=high') + generate_parser.add_argument('--fill-color', default='black', + help='QR code color') + generate_parser.add_argument('--back-color', default='white', + help='Background color') + generate_parser.add_argument('--box-size', type=int, default=10, + help='How big should each square be?') + generate_parser.add_argument('--border', type=int, default=4, + help='Border thickness') + + scan_parser = subparsers.add_parser('scan', help='Read a QR code from an image') + scan_parser.add_argument('image', help='Path to your image file') + + args = parser.parse_args() + + if not args.command: + parser.print_help() + return + + if args.command == 'generate': + generator = QRCodeGenerator(box_size=args.box_size, border=args.border) + + success = generator.generate_and_save( + data=args.data, + filename=args.output, + error_correction=args.error_correction, + fill_color=args.fill_color, + back_color=args.back_color + ) + + if success: + print(f"✅ Your QR code is ready! Saved as: {args.output}") + print(f"📝 Contains: {args.data}") + else: + print("❌ Something went wrong creating your QR code") + sys.exit(1) + + elif args.command == 'scan': + if not os.path.exists(args.image): + print(f"❌ Can't find '{args.image}'. Make sure the file exists!") + sys.exit(1) + + QRCodeScanner.scan_and_display(args.image) + + +if __name__ == '__main__': + main() diff --git a/QR-Code-Generator-Scanner/requirements.txt b/QR-Code-Generator-Scanner/requirements.txt new file mode 100644 index 0000000..ce5f479 --- /dev/null +++ b/QR-Code-Generator-Scanner/requirements.txt @@ -0,0 +1,3 @@ +qrcode[pil]==7.4.2 +Pillow==10.0.1 +pyzbar==0.1.9