import os
import cv2
import numpy as np
from pyzbar.pyzbar import decode
from PIL import Image, ImageDraw, ImageFont
import time
# 设置中文字体路径
FONT_PATH = "C:/Windows/Fonts/simsun.ttc" # Windows上的宋体
FONT_SIZE = 88 # 标题字体大小
FONT_SIZE_RESULT = 36 # 解码结果字体大小
FONT_SIZE_HISTORY = 16 # 历史记录字体大小
GREEN_COLOR = (0, 255, 0) # 绿色
RED_COLOR = (0, 0, 255) # 红色
PURPLE_COLOR = (128, 0, 128) # 紫色
YELLOW_COLOR = (0, 255, 255) # 黄色
LINE_THICKNESS_RESULT = 2 # 结果区框线宽
LINE_THICKNESS_HISTORY = 1 # 历史区框线宽
def draw_chinese_text(image, text, position, font_size, color=(255, 255, 255)):
font = ImageFont.truetype(FONT_PATH, font_size)
pil_image = Image.fromarray(image)
draw = ImageDraw.Draw(pil_image)
draw.text(position, text, font=font, fill=color)
return np.array(pil_image)
def CatchUsbVideo(window_name, camera_index):
cap = cv2.VideoCapture(camera_index)
image_folder = r'D:\Case\Code128'
image_files = [f for f in os.listdir(image_folder) if f.lower().endswith(('.png', '.jpg', '.jpeg'))]
if not image_files:
print("没有找到可用的图像文件。")
return
history = [] # 存储历史记录
current_image_index = 0 # 当前图像索引
while True:
ret, frame = cap.read()
if not ret:
print("无法读取摄像头图像.")
break
# 创建一个黑色背景
display_image = np.zeros((1080, 1920, 3), np.uint8)
# 左列(图像)
display_image[:88, :640] = (30, 30, 30) # 背景色
frame_resized = cv2.resize(frame, (640, 300)) # 调整frame大小
display_image[88:388, :640] = frame_resized # 实时图像
display_image = draw_chinese_text(display_image, " ", (10, 10), FONT_SIZE)
# 中列(解码)
display_image[:88, 640:1280] = (30, 30, 30) # 背景色
decoded_text = "等待解码,空格键一次,读取一次" # 默认文本
if history:
decoded_text = history[-1]["decoded_text"] # 显示最后一条解码结果
text_image = np.zeros((300, 640, 3), np.uint8) # 创建一个空白图像
text_image = draw_chinese_text(text_image, decoded_text, (10, 10), FONT_SIZE_RESULT)
display_image[88:388, 640:1280] = text_image # 显示解码结果
# 右列(历史记录)
display_image[:88, 1280:1920] = (30, 30, 30) # 背景色
history_text = "历史记录\n" + "\n".join(
[f"{h['time']} {h['path']} {h['decoded_text']}" for h in history[-5:]]
)
history_image = np.zeros((300, 640, 3), np.uint8) # 创建一个空白图像
history_image = draw_chinese_text(history_image, history_text, (10, 10), FONT_SIZE_HISTORY)
display_image[88:388, 1280:1920] = history_image # 显示历史记录
# 显示最终图像
cv2.imshow(window_name, display_image)
# 空格键触发图像读取
c = cv2.waitKey(1)
if c & 0xFF == ord(' '):
if current_image_index < len(image_files): # 确保索引在有效范围内
image_file = image_files[current_image_index]
image_path = os.path.join(image_folder, image_file)
# 读取图像
image = cv2.imread(image_path)
if image is None:
print(f"无法读取图像: {image_path}")
else:
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
decoded_objects = decode(gray_image)
# 处理解码结果
decoded_text = "" # 默认解码文本
for obj in decoded_objects:
decoded_text = obj.data.decode('utf-8')
print(decoded_text) # 打印解码文本
# 记录解码历史
history.append({
"time": time.strftime("%Y-%m-%d %H:%M:%S"),
"path": image_path,
"decoded_text": decoded_text
})
current_image_index += 1 # 增加当前图像索引以读取下一张图像
else:
print("没有更多的图像可读取。") # 如果没有更多图像,给出提示
elif c & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
CatchUsbVideo("camera", 0)