Files
KCGL/inventory-backend/test_barcode_limit.py

139 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import socket
import os
from io import BytesIO
from PIL import Image, ImageDraw
# 引入条形码生成库
try:
import barcode
from barcode.writer import ImageWriter
except ImportError:
print("❌ 错误: 请先安装 python-barcode (pip install python-barcode)")
exit()
class BarcodeStackTester:
# 打印机配置
PRINTER_IP = "192.168.9.205"
PRINTER_PORT = 9100
# 纸张配置: 40mm x 30mm @ 300 DPI
DOTS_PER_MM = 12
CANVAS_W = int(40 * DOTS_PER_MM) # 480px
CANVAS_H = int(30 * DOTS_PER_MM) # 360px
@staticmethod
def _generate_raw_barcode(content, bar_height_mm=4):
"""
生成原始条码图片 (不强制缩放宽度,让其自然生长)
"""
try:
# Code128 自动优化 (数字会被压缩所以20位数字其实不长)
writer = ImageWriter()
# module_width: 条码黑条的最小宽度(mm)。
# 0.2mm 在 300DPI 下约等于 2.4像素。这是一个比较清晰且节省空间的数值。
# 如果设得太大(如0.3)20位可能会超出40mm纸张。
options = {
"module_width": 0.2,
"module_height": bar_height_mm, # 条码高度
"quiet_zone": 2.0, # 两侧留白(mm)
"write_text": False, # 【关键】不写文字
"dpi": 300 # 对应打印机DPI
}
code_img = barcode.get('code128', content, writer=writer)
# 渲染到内存
buffer = BytesIO()
code_img.write(buffer, options=options)
buffer.seek(0)
return Image.open(buffer)
except Exception as e:
print(f"生成失败: {e}")
return None
def run_test(self):
# 1. 创建白色底图 (40x30mm)
canvas = Image.new('RGB', (self.CANVAS_W, self.CANVAS_H), color='white')
# 测试用例: 长度从小到大
test_lengths = [13, 15, 17, 20]
# 布局参数
current_y = 20 # 顶部起始留白 (px)
gap = 10 # 间距 (px)
print("-" * 50)
print("🚀 开始生成堆叠条码测试图...")
for length in test_lengths:
# 生成全7的内容
content = "7" * length
print(f" 正在处理: {length}位 -> {content}")
# 生成条码 (高度设为5mm左右方便在一张纸上放下4个)
bar_img = self._generate_raw_barcode(content, bar_height_mm=5)
if bar_img:
# 计算居中位置
# bar_img.width 是条码生成的自然宽度
x_pos = (self.CANVAS_W - bar_img.width) // 2
# 如果宽度超出了纸张 (x_pos < 0)说明40mm纸打不下这么多位
if x_pos < 0:
print(f" ⚠️ 警告: {length}位条码过宽 ({bar_img.width}px > {self.CANVAS_W}px),可能会被裁切!")
x_pos = 0
# 粘贴到画布
canvas.paste(bar_img, (x_pos, current_y))
# 更新Y坐标准备画下一个
current_y += bar_img.height + gap
else:
print(" 生成失败")
# 2. 保存预览图
preview_file = "test_stack_preview.jpg"
canvas.save(preview_file)
print(f"✅ 图片已生成: {preview_file} (请打开查看宽度是否超出)")
# 3. 发送打印 (二值化处理)
self._send_to_printer(canvas)
def _send_to_printer(self, img_rgb):
try:
# 转二值化 (白=1, 黑=0)
img_bw = img_rgb.convert('L').convert('1', dither=Image.Dither.NONE)
bitmap_data = img_bw.tobytes()
width_bytes = (img_bw.width + 7) // 8
height_dots = img_bw.height
# TSPL 指令
header = (
f"SIZE 40 mm, 30 mm\r\n"
"GAP 2 mm, 0 mm\r\n"
"CLS\r\n"
"DIRECTION 1\r\n"
).encode('gbk')
bitmap_cmd = f"BITMAP 0,0,{width_bytes},{height_dots},0,".encode('gbk')
footer = b"\r\nPRINT 1,1\r\n"
print("🖨️ 正在发送打印指令...")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
s.connect((self.PRINTER_IP, self.PRINTER_PORT))
s.sendall(header + bitmap_cmd + bitmap_data + footer)
s.close()
print("✅ 指令已发送")
except Exception as e:
print(f"❌ 打印失败: {e}")
if __name__ == "__main__":
tester = BarcodeStackTester()
tester.run_test()