python-全自动二维码识别

纯笔记,可以做到全屏识别二维码,自动识别,复制链接,生成简单的二维码,将识别到的内容转为txt

import pyautogui
from PIL import Image
from pyzbar.pyzbar import decode
import tkinter as tk
from tkinter import Label, Button, Listbox, Entry, END, SINGLE, filedialog
import threading
import time
import qrcode
from PIL import ImageTk
import cv2

class QRCodeScannerApp:
def init(self, root):
self.root = root
self.root.title("二维码识别器专业版")

    # 设置窗口的默认大小
    self.root.geometry("1600x1200")

    # 创建顶部功能按钮区域
    self.button_frame = tk.Frame(root)
    self.button_frame.pack(pady=10)

    self.prompt_label = Label(root, text="请选中历史记录栏的记录以启用某些功能", fg="red")
    self.prompt_label.pack(pady=5)

    # 将所有按钮移到button_frame中,并将它们设置为横向布局
    self.capture_button = Button(self.button_frame, text="捕获屏幕并识别", command=self.capture_screen_and_recognize)
    self.capture_button.grid(row=0, column=0, padx=5)

    self.batch_scan_button = Button(self.button_frame, text="导入图片并识别", command=self.batch_scan)
    self.batch_scan_button.grid(row=0, column=1, padx=5)

    self.autoscan_button = Button(self.button_frame, text="开始自动扫描", command=self.start_auto_scan)
    self.autoscan_button.grid(row=0, column=2, padx=5)

    self.stop_button = Button(self.button_frame, text="停止扫描", command=self.stop_scan, state=tk.DISABLED)
    self.stop_button.grid(row=0, column=3, padx=5)

    self.copy_button = Button(self.button_frame, text="复制选中的历史记录", command=self.copy_selected_history)
    self.copy_button.grid(row=0, column=4, padx=5)

    self.save_button = Button(self.button_frame, text="保存历史记录为TXT", command=self.save_history_to_txt)
    self.save_button.grid(row=0, column=5, padx=5)

    self.generate_button = Button(self.button_frame, text="生成二维码", command=self.generate_qrcode)
    self.generate_button.grid(row=0, column=6, padx=5)

    self.delete_history_button = Button(self.button_frame, text="删除选中历史记录", command=self.delete_selected_history)
    self.delete_history_button.grid(row=0, column=7, padx=5)

    self.clear_history_button = Button(self.button_frame, text="清空所有历史记录", command=self.clear_all_history)
    self.clear_history_button.grid(row=0, column=8, padx=5)

    self.search_button = Button(self.button_frame, text="搜索", command=self.search_history)
    self.search_button.grid(row=0, column=9, padx=5)

    self.export_button = Button(self.button_frame, text="导出QR码图像", command=self.export_qr_code)
    self.export_button.grid(row=0, column=10, padx=5)

    # 文本和输入部分
    self.label = Label(root, text="扫描结果:")
    self.label.pack(pady=10)

    self.result_label = Label(root, text="", wraplength=500)
    self.result_label.pack(pady=10)

    self.current_label = Label(root, text="当前识别:")
    self.current_label.pack(pady=10)

    # 增加宽度
    self.current_listbox_scrollbar = tk.Scrollbar(root, orient=tk.HORIZONTAL)
    self.current_listbox_scrollbar.pack(fill=tk.X)
    self.current_listbox = Listbox(root, selectmode=SINGLE, height=10, width=250,
                                   xscrollcommand=self.current_listbox_scrollbar.set)
    self.current_listbox.pack(pady=10)
    self.current_listbox_scrollbar.config(command=self.current_listbox.xview)

    self.history_label = Label(root, text="历史记录:")
    self.history_label.pack(pady=10)

    self.history_listbox_scrollbar = tk.Scrollbar(root, orient=tk.HORIZONTAL)
    self.history_listbox_scrollbar.pack(fill=tk.X)
    self.history_listbox = Listbox(root, selectmode=SINGLE, height=10, width=250,
                                   xscrollcommand=self.history_listbox_scrollbar.set)
    self.history_listbox.pack(pady=10)
    self.history_listbox_scrollbar.config(command=self.history_listbox.xview)

    self.interval_label = Label(root, text="扫描间隔时间 (毫秒):")
    self.interval_label.pack(pady=10)

    self.interval_entry = Entry(root)
    self.interval_entry.pack(pady=10)
    self.interval_entry.insert(0, "500")

    self.generate_label = Label(root, text="输入要生成的内容:")
    self.generate_label.pack(pady=10)

    self.generate_entry = Entry(root)
    self.generate_entry.pack(pady=10)

    self.search_label = Label(root, text="搜索历史:")
    self.search_label.pack(pady=10)

    self.search_entry = Entry(root)
    self.search_entry.pack(pady=10)

    # 其他属性
    self.auto_scanning = False
    self.history = []
    self.history_counter = 0
    self.seen_qrcodes = set()

def clear_all_history(self):
    self.history.clear()
    self.history_listbox.delete(0, END)

# 添加搜索历史记录的函数
def search_history(self):
    query = self.search_entry.get().lower()
    self.history_listbox.delete(0, END)
    for item in self.history:
        if query in item.lower():
            self.history_listbox.insert(END, item)

def export_qr_code(self):
    selected_index = self.history_listbox.curselection()
    if selected_index:
        selected_data = self.history[int(selected_index[0])]
        content_without_number = selected_data.split(': ', 1)[-1]

        # 使用PIL库创建QR码图像
        qr = qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4)
        qr.add_data(content_without_number)
        qr.make(fit=True)
        qr_image = qr.make_image(fill_color="black", back_color="white")

        # 选择保存路径
        file_path = filedialog.asksaveasfilename(defaultextension=".png", filetypes=[("PNG Files", "*.png")])

        # 如果用户选择了路径,则保存QR码图像
        if file_path:
            qr_image.save(file_path)

# 添加新的函数生成二维码并在新窗口中显示
def generate_qrcode(self):
    qr_data = self.generate_entry.get()
    if qr_data:
        qr = qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4)
        qr.add_data(qr_data)
        qr.make(fit=True)
        img = qr.make_image(fill_color="black", back_color="white")

        # 在新窗口中显示二维码
        new_window = tk.Toplevel(self.root)
        new_window.title("生成的二维码")

        qr_image = ImageTk.PhotoImage(img)  # 将PIL图像转换为Tkinter可使用的图像
        qr_label = Label(new_window, image=qr_image)
        qr_label.image = qr_image  # 保存图像的引用以防被垃圾收集器回收
        qr_label.pack()

def start_auto_scan(self):
    """开始自动扫描"""
    self.auto_scanning = True
    self.autoscan_button.config(state=tk.DISABLED)
    self.stop_button.config(state=tk.NORMAL)
    self.auto_scan()

def stop_scan(self):
    """停止自动扫描"""
    self.auto_scanning = False
    self.autoscan_button.config(state=tk.NORMAL)
    self.stop_button.config(state=tk.DISABLED)

def auto_scan(self):
    if self.auto_scanning:
        # 启动一个线程来异步执行屏幕捕捉和二维码识别
        threading.Thread(target=self.capture_screen_and_recognize, daemon=True).start()

        try:
            interval = int(self.interval_entry.get())
        except ValueError:
            interval = 500
        self.root.after(interval, self.auto_scan)

def capture_screen_and_recognize(self):
    start_time = time.time()
    screenshot = pyautogui.screenshot()
    image = Image.frombytes('RGB', screenshot.size, screenshot.tobytes())
    decoded_objects = decode(image)

    new_qrcodes = []

    if decoded_objects:
        for obj in decoded_objects:
            data = obj.data.decode("utf-8")
            if data not in self.seen_qrcodes:  # 如果这是一个新的二维码数据
                self.seen_qrcodes.add(data)
                new_qrcodes.append(data)

        if new_qrcodes:  # 如果有新的二维码,清除当前识别列表框
            self.current_listbox.delete(0, END)

        elapsed_time = time.time() - start_time  # 计算花费的时间
        self.result_label.config(text=f"识别到 {len(new_qrcodes)} 个新二维码,耗时 {elapsed_time:.3f} 秒")

        for i, data in enumerate(new_qrcodes):
            self.history_counter += 1
            self.current_listbox.insert(END, f"{self.history_counter}: {data}")
            self.history.append(f"{self.history_counter}: {data}")
            self.history_listbox.insert(END, f"{self.history_counter}: {data}")
    else:
        self.result_label.config(text="未找到二维码")

def copy_selected_history(self):
    selected_index = self.history_listbox.curselection()
    if selected_index:
        selected_data = self.history[int(selected_index[0])]
        # 使用字符串切片去掉标号
        content_without_number = selected_data.split(': ', 1)[-1]
        self.root.clipboard_clear()
        self.root.clipboard_append(content_without_number)
        self.root.update()

def save_history_to_txt(self):
    file_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text Files", "*.txt")])
    if file_path:
        with open(file_path, "w") as file:
            for item in self.history:
                file.write(item + "\n")

# 添加新的函数来批量扫描图片
def batch_scan(self):
    file_paths = filedialog.askopenfilenames(title="选择图片", filetypes=[("Image Files", "*.png;*.jpg;*.jpeg")])

    for file_path in file_paths:
        image = cv2.imread(file_path)

        # 调整图片大小,以适应屏幕捕获的分辨率
        scaled_image = cv2.resize(image, (self.root.winfo_screenwidth(), self.root.winfo_screenheight()))
        screenshot = Image.fromarray(cv2.cvtColor(scaled_image, cv2.COLOR_BGR2RGB))

        # 在屏幕截图上识别二维码
        decoded_objects = decode(screenshot)

        new_qrcodes = []

        if decoded_objects:
            for obj in decoded_objects:
                data = obj.data.decode("utf-8")
                if data not in self.seen_qrcodes:  # 如果这是一个新的二维码数据
                    self.seen_qrcodes.add(data)
                    new_qrcodes.append(data)

            for i, data in enumerate(new_qrcodes):
                self.history_counter += 1
                self.current_listbox.insert(END, f"{self.history_counter}: {data}")
                self.history.append(f"{self.history_counter}: {data}")
                self.history_listbox.insert(END, f"{self.history_counter}: {data}")
        else:
            self.result_label.config(text="未找到二维码")

        self.root.update()  # 更新GUI以显示结果

# 添加删除和清空历史记录的函数
def delete_selected_history(self):
    selected_index = self.history_listbox.curselection()
    if selected_index:
        del self.history[int(selected_index[0])]
        self.history_listbox.delete(selected_index)

if name == "main":
root = tk.Tk()
app = QRCodeScannerApp(root)
root.mainloop()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/119473.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

javaee实验:搭建maven+spring boot开发环境,开发“Hello,Spring Boot”应用

目录 mavenspringboot实验目的实验内容环境的搭建 在开发中,maven和spring都是非常常用、非常重要的管理工具和框架,今天就在这里使用idea进行环境的搭建和创建第一个spring程序 maven 1.1maven是一个跨平台的项目管理工具(主要管理jar包&am…

如何实现Word文档中的书签双向定位

工作中,经常需要拟定合同,一般都有固定的模板,在特定的位置填写内容。通过zOffice编辑合同文件时,可以在模板需要填写的位置预设书签,配合zOffice SDK使用,利用zOffice书签双向定位的特性,更方便…

王道p18 第12题假设 A中的 n个元素保存在一个一维数组中,请设计一个尽可能高效的算法,找出A的主元素。若存在主元素,则输出该元素:否则输出-1

视频讲解在:👇 p18 第12题 c语言实现王道数据结构课后习题_哔哩哔哩_bilibili 从前向后扫描数组元素,标记出一个可能成为主元素的元素 Num。然后重新计数,确认 Num 是否是主元素。 我们可分为以下两步: 1.选取候选的主元素。依…

CocosCreator使用物理引擎和回调

在2d中开启碰撞需要在项目设置–功能裁剪–2D物理系统【选择 基于Box2D的2D物理系统】 如果想要两个物体碰撞,则需要添加刚体和碰撞【!!重点】 设置刚体类型 可以设为四种, Static 静态刚体,零质量,零速度…

【JAVA】:万字长篇带你了解JAVA并发编程-并发设计模式【五】

目录 【JAVA】:万字长篇带你了解JAVA并发编程-并发设计模式【五】模式分类Immutability模式【不可变模式】Copy-on-Write 模式Thread Local Storage 模式线程池中使用 Guarded Suspension模式扩展 Guarded Suspension 模式 Balking模式Thread-Per-MessageWorker Thr…

【C语言 | 符号】C语言中符号易出错的地方

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…

养老院展示服务预约小程序的作用是什么

养老院无论在哪个城市都有很高需求度,不少银发人群会因为种种原因而前往,而养老院近些年来各种服务也比较完善,增加了客户信任度及接受度,但对院方来说,也存在着一些痛点: 1、品牌传播服务呈现难 养老院也…

[NLP] 使用Llama.cpp和LangChain在CPU上使用大模型

一 准备工作 下面是构建这个应用程序时将使用的软件工具: 1.Llama-cpp-python 下载llama-cpp, llama-cpp-python [NLP] Llama2模型运行在Mac机器-CSDN博客 2、LangChain LangChain是一个提供了一组广泛的集成和数据连接器,允许我们链接和编排不同的模块。可以常…

华大基因推出产前筛查产品NIFTY®,助力防控显性单基因病

随着高通量测序技术在临床应用的迅速进步,从常见的染色体非整倍体扩展到性染色体和拷贝数变异,全球范围内已经开始将无创产前检测(Non-invasive Prenatal Testing,NIPT)的应用范围逐步扩大。近日,华大基因重…

【Mybatis小白从0到90%精讲】15: Mybatis配置打印SQL日志

文章目录 前言配置日志实现前言 日志(Log)是每个程序都不可或缺的一部分,它可以帮助开发人员诊断和调试问题。Mybatis,作为一款备受赞誉的ORM框架,自然也提供了强大的日志功能。 它不仅提供了内置的标准实现,还支持集成各种主流的日志框架,让我们可以轻松地查看最终执行…

休眠和睡眠有哪些区别?如何让电脑一键休眠?

电脑中有休眠和睡眠,那么它们有什么区别呢?下面我们就通过本文来了解一下。 休眠和睡眠的区别 电脑在睡眠状态时,会切断内存之外的设备电源,电脑会进入睡眠状态,当再次唤醒电脑后,不会影响睡眠前保存好的工…

柱状图:带误差棒

误差棒可以表示样本标准差,也可以表示样本标准误。 导入库: import pandas as pd 自定义用来绘制带误差棒(样本标准差或样本标准误)的柱状图: def col(y, x, face, df, errprbarstd) : print(ggplot(df.groupby([x…

搭建WAMP网站教程(Windows+Apache+MySQL+PHP)

之前为了学习网络安全,从搭建网站学起,对网站运行有个初步的了解。 今天翻到了之前的笔记,顺手发到csdn上了。 搭建网站步骤 一、Apache 安装Apache,下载Apache之后把Apache解压,此处解压到C:\目录下 2.然后要记得安…

Notepad++中删除连续的任意n行

使用Notepad里的行标记功能,可以删除指定的任意n行。 案例1,删除sample2.dat里的第201行到第10000行。方法如下: (1) 用户NotePad打开sample2.dat,右击201行 —》“开始/结束”/开始 图(1) 选择行的起点:201 (2) 接…

Git 的基本操作 ——命令行

Git 的工作流程 详解如下: 本地仓库:是在开发人员自己电脑上的Git仓库,存放我们的代码(.git 隐藏文件夹就是我们的本地仓库) 远程仓库:是在远程服务器上的Git仓库,存放代码(可以是github.com或者gitee.com 上的仓库,或者自己该公司的服务器…

【动手学深度学习】课程笔记 05-07 线性代数、矩阵计算和自动求导

05 线性代数 1. 基础知识补充 向量相关 矩阵相关 简单来说,范数是用来衡量矩阵(张量)大小的值,范数的值有不同的规定。 2. 代码实现 仅记录一些我比较陌生的知识。 张量的克隆 A torch.arange(20, dtypetorch.float32).resh…

10个免费3D模型网站

作为一名独立游戏开发者,自己创建图形、配乐、动画和更多东西是相当具有挑战性的。 创建资产所需的成本和时间有时是许多游戏开发商无法承受的。 这就是他们选择在互联网上搜索免费内容的原因。现在,在浩瀚的内容海洋中获得如此免费的东西有点困难。 本文…

阿里云安全恶意程序检测(速通三)

阿里云安全恶意程序检测 特征工程进阶与方案优化pivot特征构建pivot特征pivot特征构建时间pivot特征构建细节特点 业务理解和结果分析结合模型理解业务多分类问题预测结果分析 特征工程进阶基于LightGBM模型验证模型结果分析模型测试 优化技巧与解决方案升级内存管理控制加速数…

Mac版eclipse如何安装,运行bpmn文件

一、下载程序包 网址:https://www.eclipse.org/downloads M2芯片安装包名称:eclipse-jee-2022-12-R-macosx-cocoa-aarch64.dmg 具体安装包版本根据自己电脑型号选择 二、eclipse安装步骤 1)双击下载的文件 2)将eclipse拖入到…

vue项目npm install报错解决

一、报错信息 node-sass4.14.1 postinstall: node scripts/build.js 二、解决方式 (1)删除未成功安装的 node_modules 文件; (2)为 node-sass 单独设置镜像源; npm config set sass_binary_sitehttps:/…