如何在Python中生成带前置FNC1的GS1 DataMatrix条码?
Python生成GS1 DataMatrix条码:添加前置FNC1的实现方案
问题描述
我需要用Python生成符合GS1标准的DataMatrix条码(GS1 DM),用于独联体国家的药品序列化场景。GS1 DM的核心是在普通DataMatrix基础上添加前置FNC1功能符号,让扫描设备识别其为GS1格式,但目前用pylibdmtx只能生成普通DM,无法添加FNC1。
待编码的数据格式是药品包装唯一标识+密钥+验证码,其中{GS}为ASCII 29的组分隔符,示例如下:
01048123231123452172KAVEK5HqOQW{GS}91KZF0{GS}92endxMQYZAymmN9rTCsWwm4gcU1oihAn726B86OLBnh0= 01048702231123452179LimKz7sKYyF{GS}91KZF0{GS}92VllFTqxoBYKxfjjd/uLpXe4Sbm3+3foXpen0DLGIgWQ=
试错过程与疑问
- 尝试过用扩展ASCII 232码等方式模拟FNC1,但这些都是普通字符,并非GS1标准的功能符号;
- 在线工具可通过
{FNC1}转义序列生成GS1 DM,但Python代码实现方式未知; - 推测需要生成库在渲染时直接添加FNC1,但没找到支持GS1 DM的Python库;
- Python的DataMatrix生成库文档匮乏,Stack Overflow也无可行方案;
- 扫描实体药品GS1 DM时,手机APP返回
{GS}开头的数据,不确定是APP处理问题还是对标准理解有误。
现有代码(基于pylibdmtx)
from PIL import Image from pylibdmtx.pylibdmtx import encode from datetime import datetime import os # 尝试过的FNC1写法均无效 # FNC1 = chr(232) # FNC1 = FNC1.encode("utf-8") # FNC1 = bytes.fromhex("E8").decode('utf-8') GS1 = chr(29) DMs = [] class Dm: def __init__(self, gtin, sn, key, code): self.gtin = gtin self.sn = sn self.key = key self.code = code self.dmImg = self.generateDmImg() def strToUTF8(self, str): return str.encode('utf_8') def __str__(self): return self.getDmContent() def getSgtin(self): return "01" + self.gtin + "21" + self.sn def getDmContent(self): str = "01" + self.gtin + "21" + self.sn + GS1 + "91" + self.key + GS1 + "92" + self.code # 尝试添加FNC1但无效 # str = FNC1 + "01" + self.gtin + "21" + self.sn + GS1 + "91" + self.key + GS1 + "92" + self.code return str def generateDmImg(self): dmContent = self.getDmContent() encoded = encode(dmContent) dmImg = Image.frombytes('RGB', (encoded.width, encoded.height), encoded.pixels) return dmImg def saveDmImgToFile(self, filename): self.dmImg.save(filename) def read_file(filename): with open(filename) as f: text_strings = f.readlines() return text_strings def getListOfDMs(text_strings): DMs = [] for text in text_strings: if len(text.strip()) > 0: text_split = text.split(";") dm = Dm(text_split[0].strip(), text_split[1].strip(), text_split[2].strip(), text_split[3].strip()) DMs.append(dm) return DMs # 主程序 res = read_file("source1.csv") DMs = getListOfDMs(res) i = 1 for dm in DMs: now = datetime.now() timestamp = now.strftime("%d_%m_%Y_%H_%M_%S") dm.saveDmImgToFile(os.path.join("results", dm.sn + "_" + timestamp + "_" + str(i) + ".png")) i += 1
source1.csv示例(四列:GTIN、SN、加密密钥、加密验证码)
04812323112345;72KAVEK5HqOQW;KZF0;endxMQYZAymmN9rTCsWwm4gcU1oihAn726B86OLBnh0= 04812323112345;79LimKz7sKYyF;KZF0;VllFTqxoBYKxfjjd/uLpXe4Sbm3+3foXpen0DLGIgWQ= 04812323112345;7GaGJ1jCrfxID;KZF0;c2l2SH8LOYmbZK95S8ENwhCQXjmwKWd5BgfA+Pwv6nE= 04812323112345;7HKrat9IGg2wZ;KZF0;cmt5NuKP23flUwDyJolFj7NMVR+K7vALjEO3ktFToGY=
解决方案:使用segno库生成GS1 DataMatrix
segno是对GS1标准支持完善的Python条码库,可直接生成带前置FNC1的GS1 DataMatrix,无需手动处理FNC1符号。
步骤1:安装库
pip install segno
步骤2:修改核心代码
替换原有的generateDmImg方法,其余逻辑保持不变:
import segno import os from datetime import datetime GS1 = chr(29) class Dm: def __init__(self, gtin, sn, key, code): self.gtin = gtin self.sn = sn self.key = key self.code = code self.dmImg = self.generateDmImg() def getDmContent(self): return f"01{self.gtin}21{self.sn}{GS1}91{self.key}{GS1}92{self.code}" def generateDmImg(self): dmContent = self.getDmContent() # 指定kind为datamatrix,gs1=True开启GS1模式,自动添加前置FNC1 dm = segno.make(dmContent, kind='datamatrix', gs1=True) return dm def saveDmImgToFile(self, filename): # scale参数控制条码放大比例,可根据需求调整 self.dmImg.save(filename, scale=5) # 读取文件、生成条码的逻辑与原代码一致,此处省略
关键说明
- FNC1是GS1标准的专用功能符号,并非普通字符,不能通过插入ASCII/UTF-8字符实现,必须由库按照标准生成;
segno的gs1=True参数会自动识别GS1应用标识符(如01、21、91等),并添加前置FNC1,生成的条码完全符合药品序列化要求;- 扫描后APP返回
{GS}开头的数据,属于APP解析逻辑的问题,标准GS1 DM扫描后应返回包含结构化信息的内容,FNC1本身不会被作为可见字符返回。
内容的提问来源于stack exchange,提问作者Pavel Legkodymov
相关产品推荐
相关产品推荐

