如何不依赖第三方服务将Base64编码的ZPL(Z64)转换为PNG图片
解决方案
问题根源
你提取到的Z64编码并非PNG/JPG等标准图片的Base64编码,而是ZPL规范中经过zlib压缩的1bit单色位图原始数据,直接解码写入文件无法生成合法图片,也无法被Jimp直接识别。
解决步骤
- 第一步:从ZPL文件中提取有效数据:先剥离ZPL命令的前缀(如
^GFA、^GF相关命令标识)、后缀(如CRC校验位、结束符),仅保留Z64编码主体部分(通常以eJ开头),同时解析^GFA命令的参数,获取位图的总字节数、每行字节数、位图高度三个关键参数,公式:位图宽度 = 每行字节数 * 8。 - 第二步:对Z64编码做Base64解码,得到zlib压缩后的二进制Buffer。
- 第三步:使用zlib解压二进制Buffer,得到1bit单色位图的原始裸数据。
- 第四步:根据宽高参数,将1bit裸数据组装为标准PNG图片。
可运行代码示例
需先安装依赖:npm install sharp
const fs = require('fs'); const zlib = require('zlib'); const sharp = require('sharp'); // 替换为你实际提取到的Z64编码和对应参数 const z64Str = 'eJzs281u4zYQAGAKLMCewmsPhfgaPWipPtIeVUC1GPiQYx6hr9FDgdL....'; const lineByteCount = 75; // 从^GFA命令参数中提取的每行字节数 const height = 600; // 从^GFA命令参数中提取的位图高度 const width = lineByteCount * 8; try { // Base64解码得到zlib压缩Buffer const compressedBuffer = Buffer.from(z64Str, 'base64'); // 解压得到1bit原始位图数据 const rawBitmap = zlib.inflateSync(compressedBuffer); // 组装为PNG并做后续处理 sharp(rawBitmap, { raw: { width: width, height: height, channels: 1, premultiplied: false } }) .threshold(128) // 二值化转为纯黑白 .rotate(90) .resize(250, 250) .toFile('./out.png', (err) => { if (err) console.log(err); else console.log('图片生成成功'); }); } catch (err) { console.log('处理失败:', err); }
注意事项
- 不要直接读取整个ZPL文件做Base64解码,必须先提取仅属于图片的Z64编码段,否则解压步骤会直接失败。
- 宽高参数必须准确,如果参数错误会导致图片内容错位、变形,参数可从
^GFA:totalByte,rowByte,height,data的命令格式中提取。 - 不想引入sharp的话也可以用Jimp逐像素绘制:遍历解压后的裸数据,每一位对应一个像素,位值为1时绘制黑色、为0时绘制白色,逐行逐位组装即可。
内容的提问来源于stack exchange,提问作者Rythelle Camargo Pereira
相关产品推荐
相关产品推荐

