QRCode使用Encoding.UTF8编码时,报错


QRCode使用Encoding.UTF8编码时,报错:

c#中索引超出数组界限



百度查了下,有位仁兄的帖子跟我的问题一样,按照帖子的办法解决了。。。yes!



http://bbs.youkuaiyun.com/topics/391847311


已解决,将qrCodeEncoder.QRCodeVersion ;改为0即可




查了下原因,下面的解释就很好:


http://blog.youkuaiyun.com/wadyloo/article/details/8787502

QRCODE的QrcodeVersion问题


为什么要在生成二维码的时候,判断字符集的长度要小于128。要知道二维码信息容量大:可容纳多达1850个大写字母或2710个数字或1108个字节,或500多个汉字,比普通条码信息容量约高几十倍。如果控制压缩内容在128个以内的话,那么二维码的优势哪里去了?


经过多次测试发现,二维码所能包含的字符信息量是由QrcodeVersion的设置值来决定的。将QrcodeVersion设置到20的时候,就已经可以容乃到300多个字节。

如果你以为这样就解决了问题的话,那么就错了,嘿嘿。如果只是修改了QrcodeVersion的值,解决的仅仅是字符集容量的问题,可是这样生成的图片无法解码。可是把字符容量控制在128个以内的时候,就可以正常的解码。难道日本人写的东西会有这么多的问题,网上搜来搜去,只能找到几个难兄难弟,但是没有找到解决的方法。

无意中打开生成的图片一看才发现了问题,生成的二维码图片的大小是会根据所压缩的信息内容而变化的,网上提供的例子是通过new BufferedImage(139, 139, BufferedImage.TYPE_INT_RGB);来创建图像对象的,默认的情况下图片的大小是139*139,这个大小是比较适合QrcodeVersion为7的情况。将图片的大小设置到300*300就可以很好的支持QrcodeVersion为20的情况,并且可以正常的解码。

QrcodeVersion的范围值是0-40,0的含义是表示压缩的信息量将会根据实际传入值确定,只有最高上限的控制,而且图片的大小将会根据信息量自动缩放。1-40的范围值,则有固定的信息量上限,而且图片的大小会固定在一个大小上,不会根据信息量的多少而变化。

以上就是在应用QRCode这个工具时遇到的一些问题,留档备案。


https://www.cnblogs.com/OuZeBo/p/6610750.html


Qrcode生成二维码的参数总结 及最小尺寸的测试





python import socket import threading import qrcode from PIL import Image import configparser import os from datetime import datetime import tempfile class QRCodePrinterServer: def __init__(self, config_file='config.ini'): # 读取配置 self.config = configparser.ConfigParser() self.config.read(config_file) # 服务器配置 self.host = self.config['SERVER'].get('host', '0.0.0.0') self.port = self.config['SERVER'].getint('port', 12345) # 二维码配置 self.qr_size = self.config['QRCODE'].getint('size', 300) self.qr_format = self.config['QRCODE'].get('format', 'PNG') self.qr_error_correction = self.config['QRCODE'].get('error_correction', 'M') self.qr_bg_color = self.config['QRCODE'].get('background_color', 'white') self.qr_fg_color = self.config['QRCODE'].get('foreground_color', 'black') # 打印机配置 self.printer_type = self.config['PRINTER'].get('printer_type', 'network') self.printer_address = self.config['PRINTER'].get('printer_address', '') self.printer_port = self.config['PRINTER'].getint('printer_port', 9100) self.printer_name = self.config['PRINTER'].get('printer_name', '') self.paper_width = self.config['PRINTER'].getint('paper_width', 80) # 错误校正级别映射 self.error_correction_map = { 'L': qrcode.constants.ERROR_CORRECT_L, 'M': qrcode.constants.ERROR_CORRECT_M, 'Q': qrcode.constants.ERROR_CORRECT_Q, 'H': qrcode.constants.ERROR_CORRECT_H } # 创建TCP服务器 self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.server_socket.bind((self.host, self.port)) self.server_socket.listen(5) print(f"QR Code Printer Server started on {self.host}:{self.port}") print(f"Printer type: {self.printer_type}, Address: {self.printer_address}") def handle_client(self, client_socket, address): """处理客户端连接""" try: print(f"Client connected from {address}") while True: # 接收数据 data = client_socket.recv(1024).decode('utf-8').strip() if not data: break print(f"Received data: {data}") # 生成二维码 qr_image_path = self.generate_qrcode(data) # 打印二维码 success = self.print_qrcode(qr_image_path, data) # 发送响应 if success: response = f"QR code generated and printed successfully: {data}" else: response = f"QR code generated but printing failed: {data}" client_socket.send(response.encode('utf-8')) print(f"Sent response: {response}") except Exception as e: print(f"Error handling client {address}: {e}") finally: client_socket.close() print(f"Client {address} disconnected") def generate_qrcode(self, data): """生成二维码图片""" try: # 配置二维码 qr = qrcode.QRCode( version=1, error_correction=self.error_correction_map.get(self.qr_error_correction, qrcode.constants.ERROR_CORRECT_M), box_size=10, border=4, ) # 添加数据 qr.add_data(data) qr.make(fit=True) # 创建二维码图片 qr_image = qr.make_image( fill_color=self.qr_fg_color, back_color=self.qr_bg_color ).convert('RGB') # 调整尺寸 qr_image = qr_image.resize((self.qr_size, self.qr_size), Image.Resampling.LANCZOS) # 保存临文件 temp_dir = tempfile.gettempdir() timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"qrcode_{timestamp}.{self.qr_format.lower()}" filepath = os.path.join(temp_dir, filename) qr_image.save(filepath, format=self.qr_format) print(f"QR code saved to: {filepath}") return filepath except Exception as e: print(f"Error generating QR code: {e}") raise def print_qrcode(self, image_path, data): """打印二维码""" try: if self.printer_type == 'network': return self._print_network(image_path, data) elif self.printer_type == 'usb': return self._print_usb(image_path, data) elif self.printer_type == 'file': return self._print_to_file(image_path, data) else: print(f"Unsupported printer type: {self.printer_type}") return False except Exception as e: print(f"Error printing QR code: {e}") return False def _print_network(self, image_path, data): """通过网络打印机打印""" try: # 创建ESC/POS指令 from escpos.printer import Network printer = Network(self.printer_address, self.printer_port) # 打印文本标题 printer.set(align='center') printer.text(f"\nQR Code: {data}\n\n") # 打印二维码 printer.qr(data, size=8) # 换行和切纸 printer.text("\n\n\n\n") printer.cut() print("QR code sent to network printer successfully") return True except ImportError: print("python-escpos library not installed. Using raw socket method.") return self._print_raw_socket(image_path, data) def _print_raw_socket(self, image_path, data): """使用原始socket发送ESC/POS指令""" try: # 连接到网络打印机 printer_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) printer_socket.settimeout(10) printer_socket.connect((self.printer_address, self.printer_port)) # ESC/POS初始化 init_cmd = b'\x1B\x40' # 设置居中 center_cmd = b'\x1B\x61\x01' # 打印标题 title = f"QR Code: {data}\n\n" title_cmd = center_cmd + title.encode('gbk') # 生成二维码ESC/POS命令 qr_cmd = self._generate_escpos_qr(data) # 换行和切纸 feed_cmd = b'\n\n\n\n' cut_cmd = b'\x1D\x56\x41\x03' # 组合所有命令 full_cmd = init_cmd + title_cmd + qr_cmd + feed_cmd + cut_cmd # 发送到打印机 printer_socket.sendall(full_cmd) printer_socket.close() print("QR code sent to printer via raw socket") return True except Exception as e: print(f"Error in raw socket printing: {e}") return False def _generate_escpos_qr(self, data): """生成ESC/POS二维码指令""" # 选择QR码模型 cmd = b'\x1D\x28\x6B\x04\x00\x31\x41\x32\x00' # 设置QR码大小 cmd += b'\x1D\x28\x6B\x03\x00\x31\x43\x08' # 设置纠错等级 cmd += b'\x1D\x28\x6B\x03\x00\x31\x45\x33' # 存储数据 data_bytes = data.encode('gbk') pL = len(data_bytes) + 3 pH = 0x00 cmd += b'\x1D\x28\x6B' + bytes([pL % 256, pL // 256, 0x31, 0x50, 0x30]) + data_bytes # 打印QR码 cmd += b'\x1D\x28\x6B\x03\x00\x31\x51\x30' return cmd def _print_usb(self, image_path, data): """通过USB打印机打印""" try: from escpos.printer import Usb # 需要提供USB Vendor ID和Product ID printer = Usb(0x04b8, 0x0e15) # 示例ID,需要根据实际打印机修改 printer.text(f"QR Code: {data}\n\n") printer.qr(data) printer.text("\n\n\n\n") printer.cut() print("QR code sent to USB printer successfully") return True except Exception as e: print(f"Error printing to USB: {e}") return False def _print_to_file(self, image_path, data): """保存到文件(用于测试)""" try: output_dir = "printed_qrcodes" os.makedirs(output_dir, exist_ok=True) timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"printed_{timestamp}.txt" filepath = os.path.join(output_dir, filename) with open(filepath, 'w', encoding='utf-8') as f: f.write(f"QR Code Data: {data}\n") f.write(f"QR Code Image: {image_path}\n") f.write(f"Printed at: {datetime.now()}\n") print(f"Print data saved to: {filepath}") return True except Exception as e: print(f"Error saving print file: {e}") return False def run(self): """启动服务器""" try: print("Server is running. Press Ctrl+C to stop.") while True: client_socket, address = self.server_socket.accept() client_thread = threading.Thread( target=self.handle_client, args=(client_socket, address) ) client_thread.start() except KeyboardInterrupt: print("\nServer is shutting down...") finally: self.server_socket.close() if __name__ == "__main__": server = QRCodePrinterServer() server.run() 运行该程序,检查是否可以优化
最新发布
10-19
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值