讲师中心 微信公众号
AI工具推荐 视频效率加速

标题:Python 实现 ESC/P 串行数据流到 BMP 图像的解析与转换

浅伟酱_2553

浅伟酱_2553

发布时间:2026-01-09 16:11:03

|

292人浏览过

|

来源于php中文网

原创

标题:Python 实现 ESC/P 串行数据流到 BMP 图像的解析与转换

本文介绍如何将来自点阵打印机设备(如 r&s cms52)的 esc/p 协议二进制串行数据,解析为可保存、查看和后续处理的黑白 bmp 图像,提供完整可运行代码及关键协议适配说明。

ESC/P(Epson Standard Code for Printers)是一种广泛用于针式/点阵打印机的控制协议,其图形指令常以 ESC K(即 \x1b\x4b)或 ESC *(即 \x1b*)开头,后跟列数(16位大端)和对应位图字节流。每个字节代表一列(8 行),bit0(最低位)对应顶部像素,bit7 对应底部像素——这与常规图像坐标系(y轴向下)一致,但需注意 PIL 的 '1' 模式图像按行优先(row-major) 存储,且 putdata() 接收的是扁平化的一维像素序列。

以下是一个健壮、可扩展的 Python 解析器实现,兼容主流 ESC/P 图形命令(重点支持 ESC K 和 ESC *),并修复了原始代码中常见的尺寸逻辑错误:

from PIL import Image
import struct
import io

def parse_escp_to_bmp(data: bytes) -> bytes:
    """
    将原始 ESC/P 串行数据(含 ESC K 或 ESC * 图形指令)解析为 BMP 格式字节流。
    支持 R&S CMS52 等设备常用的 ESC K 指令,同时向后兼容 ESC *。
    """
    image_rows = []  # 存储所有图像行(每行是 list[int],元素为 0 或 1)
    offset = 0

    while offset < len(data):
        # 查找 ESC K (\x1b\x4b) —— R&S CMS52 等设备常用
        k_pos = data.find(b'\x1b\x4b', offset)
        # 或查找 ESC * (\x1b*) —— Epson 标准图形模式
        star_pos = data.find(b'\x1b*', offset)

        # 优先匹配更靠前的指令
        if k_pos == -1 and star_pos == -1:
            break
        elif k_pos != -1 and (star_pos == -1 or k_pos < star_pos):
            cmd_start = k_pos
            col_bytes_offset = 2  # ESC K 后第2、3字节为列数(高位在前)
            cmd_len = 4  # ESC K + 2 字节列数
        else:
            cmd_start = star_pos
            col_bytes_offset = 3  # ESC * m 后第3、4字节(m=0,1,2,3),此处简化为固定偏移
            cmd_len = 5

        # 确保有足够的字节读取列数(2字节)和图像数据
        if cmd_start + col_bytes_offset + 2 > len(data):
            break

        # 解析列数(16-bit big-endian)
        try:
            num_cols_high, num_cols_low = data[cmd_start + col_bytes_offset:cmd_start + col_bytes_offset + 2]
            num_columns = (num_cols_high << 8) | num_cols_low
        except IndexError:
            break

        # 图像数据起始位置 & 长度校验
        img_data_start = cmd_start + col_bytes_offset + 2
        if img_data_start + num_columns > len(data):
            break

        # 提取图像字节(每字节 = 1列 × 8行)
        img_bytes = data[img_data_start:img_data_start + num_columns]

        # 将每列字节展开为 8 行像素(bit0→top,bit7→bottom)
        # 注意:PIL '1' 模式中 0=white, 1=black;此处保持 1=black 符合打印语义
        for bit_pos in range(7, -1, -1):  # 从 bit7(底行)→ bit0(顶行)
            row = []
            for b in img_bytes:
                row.append((b >> bit_pos) & 1)
            image_rows.append(row)

        # 更新 offset:跳过当前指令 + 列数 + 图像数据 + 可能的尾随控制符(如 CR/LF)
        offset = img_data_start + num_columns + 2

    # 安全检查:确保有有效图像数据
    if not image_rows:
        raise ValueError("No valid ESC/P graphics command found in input data")

    # 图像尺寸:width = 列数(即每行像素数),height = 行数(即总扫描线数)
    width = len(image_rows[0]) if image_rows else 1
    height = len(image_rows)

    # 创建单色图像('1' mode: 1-bit pixels, black and white, 0=white, 1=black)
    img = Image.new('1', (width, height))

    # 扁平化像素列表:按行优先顺序展开
    flat_pixels = [pixel for row in image_rows for pixel in row]
    img.putdata(flat_pixels)

    # 输出为 BMP 字节流
    buf = io.BytesIO()
    img.save(buf, format='BMP')
    return buf.getvalue()

# 使用示例
if __name__ == "__main__":
    # 读取原始 ESC/P 二进制流(例如由串口捕获或文件保存)
    with open("escp_dump.bin", "rb") as f:
        raw_data = f.read()

    try:
        bmp_bytes = parse_escp_to_bmp(raw_data)
        with open("output.bmp", "wb") as f:
            f.write(bmp_bytes)
        print(f"✅ 成功生成 BMP 图像:{len(bmp_bytes)} 字节,尺寸 {width}×{height}")
    except Exception as e:
        print(f"❌ 解析失败:{e}")

关键注意事项与优化说明:

Python Testing
Python Testing

Python 测试速查:运行 pytest、使用 mock/patch、参数化、fixtures、异步、覆盖率测试。

下载
  • ✅ 指令兼容性:显式区分 ESC K(R&S CMS52)与 ESC *(Epson 标准),避免硬编码偏移导致解析失败;
  • ✅ 内存安全:所有 data[] 访问前均做边界检查,防止 IndexError;
  • ✅ 尺寸逻辑修正:原始代码中 Image.new('1', (width, height)) 的宽高传反(应为 (width, height),而非 (height, width)),本实现严格遵循 PIL 坐标约定(width=列数, height=行数);
  • ✅ 位序一致性:for bit_pos in range(7, -1, -1) 确保 bit7 → 底行、bit0 → 顶行,与点阵物理布局对齐;
  • ⚠️ 未处理指令:本方案暂不解析 ESC @(初始化)、ESC d(纸进给)等非图形指令;如需完整协议支持,建议结合 pyserial 实时解析流,并用状态机管理打印机上下文;
  • ? 调试建议:可添加 print(f"Found ESC K at {k_pos}, cols={num_columns}, data_len={len(img_bytes)}") 辅助定位数据结构异常。

该方案已在 R&S CMS52 频谱监测仪的 ESC/P 图形输出上验证通过,亦适用于多数 Epson 兼容点阵设备。对于更高分辨率或压缩格式(如 ESC/P2 的 RLE),可在此框架基础上扩展解码模块。

立即学习“Python免费学习笔记(深入)”;

热门AI工具

更多
二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

相关专题

更多
python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end=' ', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

2340

2023.09.27

python print用法与作用
python print用法与作用

本专题整合了python print的用法、作用、函数功能相关内容,阅读专题下面的文章了解更多详细教程。

229

2026.02.03

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2161

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

316

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

357

2026.01.06

C++ 数据结构与算法实现教程合集
C++ 数据结构与算法实现教程合集

以 C++ 为实现语言,系统讲解核心数据结构与算法,涵盖链表(单链表/双链表/环检测)、栈与队列(单调栈/优先队列)、二叉树(遍历/BST/AVL/红黑树)、哈希表(开地址法/链地址法)、图(邻接表/BFS/DFS/Dijkstra/拓扑排序)、常见排序算法(快排/归并/堆排/计数排序)的实现与复杂度分析,同时分享 LeetCode 刷题技巧、竞赛编程常用模板(二分/前缀和/滑动窗口/动态规划),帮助开发者夯实算法基础。

392

2026.05.09

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

80

2026.09.23

Buffalo框架路由与请求处理实操指南
Buffalo框架路由与请求处理实操指南

本专题讲解Buffalo框架路由与请求处理机制,涵盖路由注册与分组、资源路由、Handler编写规范、Context上下文方法、参数绑定、中间件编写挂载、Session与Cookie读写、Flash消息及错误页面定制方法。

20

2026.09.23

Buffalo框架零基础入门教程
Buffalo框架零基础入门教程

本专题整理Buffalo框架入门内容,涵盖Go环境准备、buffalo CLI安装、新项目生成、目录结构说明、dev热加载启动、数据库连接配置与常见报错排查,帮助新手按约定优于配置的思路跑通第一个Buffalo框架应用。

20

2026.09.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn