hier ein Barcodescanner.
Code: Alles auswählen
#! /usr/bin/env python
# -*- coding: utf-8
import tkinter as tk
import cv2
from PIL import Image, ImageTk, ImageDraw
from functools import partial
from pyzbar.pyzbar import decode
WIDTH = 320
HEIGHT = 240
DEFAULT_CAM_ID = -1
class BarCodeCam(object):
PROPID_WIDTH = 3
PROPID_HEIGHT = 4
def __init__(self, cam_id = DEFAULT_CAM_ID):
self.cam = cv2.VideoCapture(cam_id)
if not self.cam.isOpened():
raise RuntimeError("can not open camera {0!r}".format(
cam_id))
self.width = int(self.cam.get(self.PROPID_WIDTH))
self.height = int(self.cam.get(self.PROPID_HEIGHT))
self.target_marks = ((self.width / 2 - 200,
self.height / 2,
self.width / 2 - 125,
self.height / 2,
4, "blue"),
(self.width / 2 + 125,
self.height / 2,
self.width / 2 + 200,
self.height / 2,
4, "blue"),
(self.width / 2 -200,
self.height / 2 -25,
self.width / 2 - 200,
self.height / 2 + 25,
4, "blue"),
(self.width / 2 + 200,
self.height / 2 -25,
self.width / 2 + 200,
self.height / 2 + 25,
4, "blue"),
(self.width / 2 - 125,
self.height / 2 - 125,
self.width / 2 - 125,
self.height / 2 + 125,
4, "green"),
(self.width / 2 + 125,
self.height / 2 - 125,
self.width/ 2 + 125,
self.height / 2 + 125,
4, "green"),
(self.width / 2 - 125,
self.height / 2 - 125,
self.width / 2 + 125,
self.height / 2 - 125,
4, "green"),
(self.width / 2 - 125,
self.height/ 2 + 125,
self.width / 2 + 125,
self.height/ 2 + 125,
4, "green"))
self.data = None
@property
def size(self):
return self.width, self.height
def __enter__(self):
return self
def __exit__(self, *args):
self.release()
def get_text(self, lang = "deu"):
return pyocr.tesseract.image_to_string(
self.get_image(),
lang=lang,
builder=pyocr.builders.TextBuilder())
def get_image(self, border = True):
self.data = None
frame = self.get_frame()
image = Image.frombytes("RGB",
self.size,
frame,
"raw",
"BGR")
image_draw = ImageDraw.Draw(image)
if border:
self.draw_target_mark(image_draw)
for barcode in decode(self.get_frame()):
self.data = barcode.data
(x, y, w, h) = barcode.rect
image_draw.rectangle((x, y, x + w, y + h), width = 4, outline="red")
return image
def draw_target_mark(self, image_draw):
for line_properities in self.target_marks:
x_1, y_1, x_2, y_2, width, color = line_properities
image_draw.line((x_1, y_1, x_2, y_2), width = width, fill = color)
def get_frame(self):
state, frame = self.cam.read()
if not state:
raise RuntimeError("could not read image")
else:
return frame
def release(self):
self.cam.release()
class OCRCamUI(tk.Frame):
def __init__(self, parent, bar_code_cam, width, height,
update_interval = 20):
tk.Frame.__init__(self, parent)
self.parent = parent
self.bar_code_cam = bar_code_cam
self.barcode_text = None
self.width = width
self.height = height
self.update_interval = update_interval
self.after_id = None
self.tk_image = None
self.top_level = False
self.image_label = tk.Label(self)
self.image_label.pack()
def run(self):
try:
tk_image = self.bar_code_cam.get_image().resize((self.width,
self.height))
except RuntimeError:
self.raise_cam_id_error()
return
self.tk_image = ImageTk.PhotoImage(tk_image)
self.image_label.config(image = self.tk_image)
if self.bar_code_cam.data and self.top_level == False:
self.top_level = True
self.get_data()
self.after_id = self.after(self.update_interval, self.run)
def get_data(self):
top = tk.Toplevel()
def set_toplevel():
self.top_level = False
top.destroy()
top.protocol("WM_DELETE_WINDOW", set_toplevel)
top.title("BARCODE SCAN")
text_box=tk.Text(top)
text_box.pack()
try:
text_box.insert(tk.END, self.bar_code_cam.data)
except RuntimeError as e:
print(e)
text_box.insert(tk.END, "NO CAM")
text_box.tag_config("sel", background = "skyblue")
text_box.bind("<ButtonRelease-1>", partial(self.paste_to_clipboard,
top,
text_box))
def paste_to_clipboard(self, top, text_box, event):
top.clipboard_clear()
try:
self.parent.clipboard_append(text_box.get(tk.SEL_FIRST,
tk.SEL_LAST))
except tk.TclError:
top.title("BARCODE--> NO TEXT SELECTED")
else:
top.title("BARCODE--> TEXT COPIED TO CLIPBOARD")
def raise_cam_id_error(self):
self.after_cancel(self.after_id)
self.image_label.config(image = "", text = '> NO CAM <',
font = 'Arial 60')
def release(self):
self.after_cancel(self.after_id)
self.parent.destroy()
def main():
root = tk.Tk()
root.title("BARCODE CAM")
root.resizable(0, 0)
try:
with BarCodeCam() as bar_code_cam:
bar_code_cam_ui = OCRCamUI(root, bar_code_cam, WIDTH, HEIGHT)
bar_code_cam_ui.pack()
bar_code_cam_ui.run()
root.protocol("WM_DELETE_WINDOW", bar_code_cam_ui.release)
root.mainloop()
except RuntimeError:
tk.Label(root, text = "can not open camera {0!r}".format(
DEFAULT_CAM_ID), font = "Arial 20", height = 10).pack()
root.mainloop()
if __name__ == "__main__":
main()