You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过Socket在热敏打印机打印图片的Python技术求助

解决网络热敏打印机Socket打印图片的问题

问题原因

直接发送原始JPG字节流给打印机,打印机会将这些字节解析为ASCII字符输出,而非图片数据,所以出现乱码/无限字符流。热敏打印机(多数遵循ESC/POS协议)需要先接收控制指令,切换到图片打印模式,再发送处理后的图片数据。

解决方案

方法1:使用现成ESC/POS库(推荐)

python-escpos库已封装所有ESC/POS指令,支持网络打印机,无需手动处理指令:

首先安装库:

pip install python-escpos

编写Socket打印脚本:

from escpos.printer import Network

# 连接网络打印机
p = Network("192.168.1.56", port=9100)

# 打印图片(自动处理格式转换和指令封装)
p.image("immagine.jpg")

# 切纸(可选,根据打印机支持)
p.cut()

# 关闭连接
p.close()

方法2:手动构造ESC/POS指令(适合自定义需求)

若不想依赖第三方库,需先将JPG转为单色位图(热敏打印机通常仅支持黑白),再用ESC/POS指令包裹发送:

核心步骤:

  1. 用Pillow将图片转为适配打印机宽度的单色位图
  2. 发送ESC/POS指令ESC *切换到位图模式
  3. 逐行发送位图数据
  4. 发送换行/切纸指令

示例代码:

import socket
from PIL import Image

def convert_to_printer_image(image_path, max_width=384):
    # 转换为单色位图,适配多数热敏打印机的384像素宽度
    img = Image.open(image_path).convert("L")
    width, height = img.size
    if width > max_width:
        ratio = max_width / width
        height = int(height * ratio)
        img = img.resize((max_width, height), Image.Resampling.LANCZOS)
    # 转为1位深度黑白图
    img = img.point(lambda x: 0 if x < 128 else 255, '1')
    return img

def send_image_to_printer(ip, port, img):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((ip, port))
    
    width = img.width
    height = img.height
    # ESC/POS位图指令:ESC * m nL nH d1...dk,m=0表示8点密度
    byte_width = (width + 7) // 8
    cmd = b'\x1B\x2A' + b'\x00' + byte_width.to_bytes(2, byteorder='little')
    
    # 逐行发送位图数据
    for y in range(height):
        row = []
        for x in range(byte_width):
            byte = 0
            for bit in range(8):
                pos_x = x * 8 + bit
                if pos_x < width and img.getpixel((pos_x, y)) == 0:
                    byte |= (1 << (7 - bit))
            row.append(byte)
        sock.sendall(cmd + bytes(row) + b'\x0A')
    
    # 切纸指令
    sock.sendall(b'\x1B\x69')
    sock.close()

# 执行打印
img = convert_to_printer_image("immagine.jpg")
send_image_to_printer("192.168.1.56", 9100, img)

关于你找到的脚本适配

你提到的脚本核心是将图片转换为适合热敏打印机的格式并生成ESC/POS指令流,完全可以适配成Socket传输:

  1. 保留脚本中图片处理、指令生成的逻辑
  2. 将原来的打印输出逻辑替换为Socket发送,用sock.sendall()发送生成的指令流给打印机即可
  3. 这种方式适合需要高度自定义打印逻辑的场景,和手动构造指令的思路一致

内容的提问来源于stack exchange,提问作者Davide Michelotti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 10:30:46