Last active
September 28, 2026 21:33
-
-
Save andrewgilmartin/da87f59987be51cfbb126f736fedce23 to your computer and use it in GitHub Desktop.
CLI tool to read QR code from MacOS camera image
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env uv run --script | |
| # /// script | |
| # dependencies = [ | |
| # "opencv-python", | |
| # ] | |
| # /// | |
| import cv2 | |
| import sys | |
| def main(): | |
| # Initialize the OpenCV QR Code detector | |
| detector = cv2.QRCodeDetector() | |
| # Open connection to the default camera (0 is usually the built-in FaceTime camera) | |
| cap = cv2.VideoCapture(0) | |
| if not cap.isOpened(): | |
| print("Error: Could not open the macOS camera.", file=sys.stderr) | |
| print("Please ensure terminal/IDE has Camera permissions in System Settings.", file=sys.stderr) | |
| return | |
| print("QR Code Scanner started. Point your camera at a QR code.") | |
| print("Press 'q' in the video window to quit.") | |
| previous_data = "" | |
| while True: | |
| # Capture frame-by-frame | |
| ret, frame = cap.read() | |
| if not ret: | |
| print("Failed to grab frame.") | |
| break | |
| # Detect and decode the QR code from the frame | |
| data, bbox, _ = detector.detectAndDecode(frame) | |
| # If a QR code is detected and contains data | |
| if data: | |
| if data != previous_data: | |
| print(f"\n[+] Decoded Data: {data}") | |
| previous_data = data | |
| # Optional: Draw a bounding box around the detected QR code | |
| if bbox is not None and len(bbox) > 0: | |
| # bbox returns coordinates as a float array; convert to integers for drawing | |
| pts = bbox[0].astype(int) | |
| n = len(pts) | |
| for i in range(n): | |
| cv2.line(frame, tuple(pts[i]), tuple(pts[(i+1) % n]), (0, 255, 0), 3) | |
| # Display the live camera feed | |
| cv2.imshow("macOS Camera - QR Scanner", frame) | |
| # Stop the loop if 'q' key is pressed | |
| if cv2.waitKey(1) & 0xFF == ord('q'): | |
| break | |
| # Clean up and close windows | |
| cap.release() | |
| cv2.destroyAllWindows() | |
| print("\nScanner closed.") | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment