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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 21:10:26