From 0ad3a8554e5c398f4978df691195e6b303881f73 Mon Sep 17 00:00:00 2001 From: Soumyadev Saha Date: Fri, 17 May 2024 10:43:28 +0530 Subject: [PATCH 1/3] added qrcode encoder and decoder miniproject --- .../mini-projects/qr_code_encoder_decoder.py | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 contrib/mini-projects/qr_code_encoder_decoder.py diff --git a/contrib/mini-projects/qr_code_encoder_decoder.py b/contrib/mini-projects/qr_code_encoder_decoder.py new file mode 100644 index 0000000..1180502 --- /dev/null +++ b/contrib/mini-projects/qr_code_encoder_decoder.py @@ -0,0 +1,133 @@ +import tkinter as tk +from tkinter import messagebox, filedialog +import qrcode +from PIL import Image, ImageTk +import cv2 +from pyzbar.pyzbar import decode + +class QRCodeApp: + def _init_(self, root): + self.root = root + self.root.title("QR Code Encoder and Decoder") + + self.main_frame = tk.Frame(root) + self.main_frame.pack(pady=20) + self.main_frame.pack(padx=30) + + self.button1 = tk.Button(self.main_frame, text="Encode Text to QR Code", command=self.show_encode_screen) + self.button1.pack(pady=10) + + self.button2 = tk.Button(self.main_frame, text="Decode QR Code from Camera", command=self.show_decode_screen) + self.button2.pack(pady=10) + + self.encode_frame = None + self.decode_frame = None + + def show_encode_screen(self): + self.clear_frame() + self.encode_frame = tk.Frame(self.root) + self.encode_frame.pack(pady=20) + self.encode_frame.pack(padx=30) + + self.text_box = tk.Entry(self.encode_frame, width=50) + self.text_box.pack(pady=10) + + self.convert_button = tk.Button(self.encode_frame, text="Convert", command=self.convert_to_qr) + self.convert_button.pack(pady=10) + + self.back_button = tk.Button(self.encode_frame, text="Back", command=self.show_main_screen) + self.back_button.pack(pady=10) + + def convert_to_qr(self): + text = self.text_box.get() + if text: + qr = qrcode.make(text) + file_path = filedialog.asksaveasfilename(defaultextension=".png", filetypes=[("PNG files", "*.png")]) + if file_path: + qr.save(file_path) + messagebox.showinfo("Success", "QR Code saved successfully!") + else: + messagebox.showwarning("Input Error", "Please enter text to convert to QR Code.") + + def show_decode_screen(self): + self.clear_frame() + self.decode_frame = tk.Frame(self.root) + self.decode_frame.pack(pady=10) + self.decode_frame.pack(padx=50) + + self.start_camera_button = tk.Button(self.decode_frame, text="Start Camera", command=self.start_camera) + self.start_camera_button.pack(pady=0) + + self.back_button = tk.Button(self.decode_frame, text="Back", command=self.show_main_screen) + self.back_button.pack(pady=10) + + def start_camera(self): + cap = cv2.VideoCapture(0) + found_qr = False + + while not found_qr: + ret, frame = cap.read() + if not ret: + break + + decoded_objects = decode(frame) + for obj in decoded_objects: + points = obj.polygon + if len(points) > 4: + hull = cv2.convexHull(points, returnPoints=True) + else: + hull = points + + n = len(hull) + for j in range(0, n): + cv2.line(frame, tuple(hull[j]), tuple(hull[(j+1) % n]), (255, 0, 0), 3) + + qr_text = obj.data.decode("utf-8") + found_qr = True + cv2.putText(frame, qr_text, (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) + self.display_decoded_text(qr_text) + + cv2.imshow("QR Code Scanner", frame) + if cv2.waitKey(1) & 0xFF == ord('q'): + break + + cap.release() + cv2.destroyAllWindows() + + def display_decoded_text(self, text): + messagebox.showinfo("Decoded Text", text) + # create a new text file and write the decoded text to it + file_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files", "*.txt")]) + if file_path: + with open(file_path, "w") as f: + f.write(text) + messagebox.showinfo("Success", "Decoded text saved successfully!") + + def show_main_screen(self): + self.clear_frame() + self.main_frame.pack(pady=20) + self.main_frame.pack(padx=30) + + # reset the encode and decode frames, basically re-run the _init_ method + self.button1 = tk.Button(self.main_frame, text="Encode Text to QR Code", command=self.show_encode_screen) + self.button1.pack(pady=10) + + self.button2 = tk.Button(self.main_frame, text="Decode QR Code from Camera", command=self.show_decode_screen) + self.button2.pack(pady=10) + + self.encode_frame = None + self.decode_frame = None + + + + def clear_frame(self): + for widget in self.root.winfo_children(): + widget.pack_forget() + widget.destroy() + self.main_frame = tk.Frame(self.root) + self.main_frame.pack(pady=20) + +if __name__ == "__main__": + root = tk.Tk() + app = QRCodeApp(root) + root.mainloop() \ No newline at end of file From 2424e64f45d321716d4ed75f7c6095a4d1b3a8cd Mon Sep 17 00:00:00 2001 From: Soumyadev Saha Date: Fri, 17 May 2024 22:04:27 +0530 Subject: [PATCH 2/3] updated comments and added .md files --- contrib/mini-projects/index.md | 2 +- .../mini-projects/qr_code_encoder_decoder.md | 85 +++++++++++++++++++ .../mini-projects/qr_code_encoder_decoder.py | 67 +++++++++------ 3 files changed, 127 insertions(+), 27 deletions(-) create mode 100644 contrib/mini-projects/qr_code_encoder_decoder.md diff --git a/contrib/mini-projects/index.md b/contrib/mini-projects/index.md index 82596a2..75869b1 100644 --- a/contrib/mini-projects/index.md +++ b/contrib/mini-projects/index.md @@ -1,3 +1,3 @@ # List of sections -- [Section title](filename.md) +- [QR Code Encoder Decoder](qr_code_encoder_decoder.md) diff --git a/contrib/mini-projects/qr_code_encoder_decoder.md b/contrib/mini-projects/qr_code_encoder_decoder.md new file mode 100644 index 0000000..077bf36 --- /dev/null +++ b/contrib/mini-projects/qr_code_encoder_decoder.md @@ -0,0 +1,85 @@ +# QR Code Encoder and Decoder Application + +## Overview + +This project is a QR code encoder and decoder application built using Python and Tkinter. The application allows users to: + +1. Encode text into a QR code and save it as an image file. +2. Decode QR codes using a webcam and save the decoded text to a file. + +## Features + +- **Encode Text to QR Code**: Converts user-provided text into a QR code and saves it as a PNG image. +- **Decode QR Code from Camera**: Captures QR codes using the webcam, decodes the text, and allows saving the decoded text to a file. + +## Requirements + +- Python 3.x +- Tkinter +- qrcode +- Pillow (PIL) +- OpenCV +- pyzbar + +## Installation + +1. **Install Python**: Make sure you have Python 3.x installed on your system. + +2. **Install Required Libraries**: + ```bash + pip install qrcode[pil] + pip install pillow + pip install opencv-python + pip install pyzbar + ``` + +## Usage + +1. **Run the Application**: + ```bash + python QRCodeApp.py + ``` + +2. **Encode Text to QR Code**: + - Click the "Encode Text to QR Code" button. + - Enter the text you want to encode in the text box. + - Click the "Convert" button. + - Save the generated QR code image. + +3. **Decode QR Code from Camera**: + - Click the "Decode QR Code from Camera" button. + - Click "Start Camera" to begin scanning. + - The application will decode the QR code and display the text. + - Save the decoded text to a file. + +## Project Structure + +- `qr_code_encoder_decoder.py`: Main application script containing the Tkinter GUI and logic for encoding and decoding QR codes. +- `qr_code_encoder_decoder.md`: Project documentation. + +## Libraries Used + +- **Tkinter**: For the graphical user interface. +- **qrcode**: To generate QR codes from text. +- **Pillow (PIL)**: For handling image files. +- **OpenCV**: For capturing video from the webcam and processing frames. +- **pyzbar**: For decoding QR codes from images. + +## How It Works + +### Encoding QR Code + +1. The user enters text into a text box. +2. The text is converted to a QR code using the `qrcode` library. +3. The generated QR code is saved as a PNG image. + +### Decoding QR Code + +1. The user starts the camera using the OpenCV library. +2. Frames from the webcam are captured and processed to detect QR codes. +3. Detected QR codes are decoded using the `pyzbar` library. +4. The decoded text is displayed to the user and can be saved to a text file. + +## License + +This project is licensed under the MIT License. diff --git a/contrib/mini-projects/qr_code_encoder_decoder.py b/contrib/mini-projects/qr_code_encoder_decoder.py index 1180502..fddca62 100644 --- a/contrib/mini-projects/qr_code_encoder_decoder.py +++ b/contrib/mini-projects/qr_code_encoder_decoder.py @@ -6,70 +6,83 @@ import cv2 from pyzbar.pyzbar import decode class QRCodeApp: - def _init_(self, root): + def __init__(self, root): self.root = root self.root.title("QR Code Encoder and Decoder") - + + # Main frame that contains the primary buttons self.main_frame = tk.Frame(root) self.main_frame.pack(pady=20) self.main_frame.pack(padx=30) - + + # Button to show the encode screen self.button1 = tk.Button(self.main_frame, text="Encode Text to QR Code", command=self.show_encode_screen) self.button1.pack(pady=10) - + + # Button to show the decode screen self.button2 = tk.Button(self.main_frame, text="Decode QR Code from Camera", command=self.show_decode_screen) self.button2.pack(pady=10) - + self.encode_frame = None self.decode_frame = None def show_encode_screen(self): + # Clear the main frame and show the encode frame self.clear_frame() self.encode_frame = tk.Frame(self.root) self.encode_frame.pack(pady=20) self.encode_frame.pack(padx=30) - + + # Text box to enter text for QR code self.text_box = tk.Entry(self.encode_frame, width=50) self.text_box.pack(pady=10) - + + # Button to convert text to QR code self.convert_button = tk.Button(self.encode_frame, text="Convert", command=self.convert_to_qr) self.convert_button.pack(pady=10) - + + # Button to go back to the main screen self.back_button = tk.Button(self.encode_frame, text="Back", command=self.show_main_screen) self.back_button.pack(pady=10) def convert_to_qr(self): text = self.text_box.get() if text: + # Generate QR code from text qr = qrcode.make(text) + # Save the QR code as an image file file_path = filedialog.asksaveasfilename(defaultextension=".png", filetypes=[("PNG files", "*.png")]) if file_path: qr.save(file_path) messagebox.showinfo("Success", "QR Code saved successfully!") else: messagebox.showwarning("Input Error", "Please enter text to convert to QR Code.") - + def show_decode_screen(self): + # Clear the main frame and show the decode frame self.clear_frame() self.decode_frame = tk.Frame(self.root) self.decode_frame.pack(pady=10) self.decode_frame.pack(padx=50) - + + # Button to start the camera for QR code scanning self.start_camera_button = tk.Button(self.decode_frame, text="Start Camera", command=self.start_camera) self.start_camera_button.pack(pady=0) - + + # Button to go back to the main screen self.back_button = tk.Button(self.decode_frame, text="Back", command=self.show_main_screen) self.back_button.pack(pady=10) - + def start_camera(self): cap = cv2.VideoCapture(0) found_qr = False - + while not found_qr: ret, frame = cap.read() if not ret: break - + + # Decode QR code from the camera frame decoded_objects = decode(frame) for obj in decoded_objects: points = obj.polygon @@ -77,50 +90,52 @@ class QRCodeApp: hull = cv2.convexHull(points, returnPoints=True) else: hull = points - + n = len(hull) for j in range(0, n): cv2.line(frame, tuple(hull[j]), tuple(hull[(j+1) % n]), (255, 0, 0), 3) - + + # Extract and display the decoded text qr_text = obj.data.decode("utf-8") found_qr = True cv2.putText(frame, qr_text, (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) self.display_decoded_text(qr_text) - + cv2.imshow("QR Code Scanner", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break - + cap.release() cv2.destroyAllWindows() - + def display_decoded_text(self, text): + # Show the decoded text in a message box messagebox.showinfo("Decoded Text", text) - # create a new text file and write the decoded text to it + # Save the decoded text to a text file file_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files", "*.txt")]) if file_path: with open(file_path, "w") as f: f.write(text) messagebox.showinfo("Success", "Decoded text saved successfully!") - + def show_main_screen(self): + # Clear the current frame and show the main frame self.clear_frame() self.main_frame.pack(pady=20) self.main_frame.pack(padx=30) - # reset the encode and decode frames, basically re-run the _init_ method + # Re-create the buttons for encoding and decoding self.button1 = tk.Button(self.main_frame, text="Encode Text to QR Code", command=self.show_encode_screen) self.button1.pack(pady=10) - + self.button2 = tk.Button(self.main_frame, text="Decode QR Code from Camera", command=self.show_decode_screen) self.button2.pack(pady=10) self.encode_frame = None self.decode_frame = None - - def clear_frame(self): + # Clear all widgets from the current frame for widget in self.root.winfo_children(): widget.pack_forget() widget.destroy() @@ -130,4 +145,4 @@ class QRCodeApp: if __name__ == "__main__": root = tk.Tk() app = QRCodeApp(root) - root.mainloop() \ No newline at end of file + root.mainloop() From 4699934a85ff525416b577bb60bfd03f5b5ffa24 Mon Sep 17 00:00:00 2001 From: Soumyadev Saha Date: Fri, 17 May 2024 22:14:43 +0530 Subject: [PATCH 3/3] updated forlder structure --- .../qr_code_project.py} | 0 .../readme.md} | 4 ++-- contrib/mini-projects/index.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename contrib/mini-projects/{qr_code_encoder_decoder.py => QRCodeEncoderDecoder/qr_code_project.py} (100%) rename contrib/mini-projects/{qr_code_encoder_decoder.md => QRCodeEncoderDecoder/readme.md} (92%) diff --git a/contrib/mini-projects/qr_code_encoder_decoder.py b/contrib/mini-projects/QRCodeEncoderDecoder/qr_code_project.py similarity index 100% rename from contrib/mini-projects/qr_code_encoder_decoder.py rename to contrib/mini-projects/QRCodeEncoderDecoder/qr_code_project.py diff --git a/contrib/mini-projects/qr_code_encoder_decoder.md b/contrib/mini-projects/QRCodeEncoderDecoder/readme.md similarity index 92% rename from contrib/mini-projects/qr_code_encoder_decoder.md rename to contrib/mini-projects/QRCodeEncoderDecoder/readme.md index 077bf36..8f558d1 100644 --- a/contrib/mini-projects/qr_code_encoder_decoder.md +++ b/contrib/mini-projects/QRCodeEncoderDecoder/readme.md @@ -54,8 +54,8 @@ This project is a QR code encoder and decoder application built using Python and ## Project Structure -- `qr_code_encoder_decoder.py`: Main application script containing the Tkinter GUI and logic for encoding and decoding QR codes. -- `qr_code_encoder_decoder.md`: Project documentation. +- `qr_code_project.py`: Main application script containing the Tkinter GUI and logic for encoding and decoding QR codes. +- `readme.md`: Project documentation. ## Libraries Used diff --git a/contrib/mini-projects/index.md b/contrib/mini-projects/index.md index 75869b1..615ccd2 100644 --- a/contrib/mini-projects/index.md +++ b/contrib/mini-projects/index.md @@ -1,3 +1,3 @@ # List of sections -- [QR Code Encoder Decoder](qr_code_encoder_decoder.md) +- [QR Code Encoder Decoder](./QRCodeEncoderDecoder/readme.md)