使用 Python 编写各种条形码
学习如何使用 python-barcode 库编写各种类型的线性条形码。
我们将在此课程中使用 python-barcode 库来实现 Python 中的条形码。
- Code 39
- Code 128
- PZN7(又称:PZN)
- ISBN-13
- ISBN-10
- ISSN
- UPC-A
- EAN-8
- EAN-13
- EAN14
- JAN
- GS1-128
在本例中,我们将使用 EAN-13 类型的条形码为一些店内商品创建标签。如前所述,我们可以将前两位数字设置为 20 到 29 之间的任意数字,以用于此目的。
最后一位是模 10 校验位。我们可自由使用其余 10 位数字。也可以选择不使用最后一位作为校验码,在这种情况下,最后一位将被设为 0。
首先导入主要库。我们将使用 EAN13 类来创建 EAN-13 条形码。ImageWriter 和 SVGWriter 分别用于将渲染后的条形码输出为图像文件或 SVG 文件。
1from barcode import EAN13 2from barcode.writer import ImageWriter 3from barcode.writer import SVGWriter 4import random
我们还将使用 random 库生成随机数字字符串。先进行如下操作:
1def createRandomDigitString(n): 2 return ''.join([str(random.randint(0,9)) for _ in range(n)]) 3 4barcodeString = createRandomDigitString(10) 5print(barcodeString) 6 7barcodeString = "20" + barcodeString 8print(barcodeString)
接下来,我们可以开始创建一些条形码。
1barcodeString = "20" + createRandomDigitString(10) 2print(barcodeString) 3 4with open('output/EAN13.jpg', 'wb') as f: 5 EAN13(barcodeString, writer=ImageWriter()).write(f) 6 7with open('output/EAN13.svg', 'wb') as f: 8 EAN13(barcodeString, writer=SVGWriter()).write(f) 9 10with open('output/EAN13_gb.jpg', 'wb') as f: 11 EAN13(barcodeString, writer=ImageWriter(), guardbar=True).write(f)
上述代码的第一个结果是一个包含 10 位随机数字的字符串。该随机字符串仅用于演示目的。如果需要,当然可以手动构造特定的 10 位数字字符串。在实际生产环境中,显然不应采用这种方式,而应手动构造特定的数字字符串。
第二个输出中,我们在随机数字字符串前添加了代码 20,表示该条形码仅用于店内用途。
以下是快速生成条形码的几个示例:
-
第 4–5 行:第一个示例创建一个包含 EAN-13 条形码的 JPG 图像文件。
-
第 7–8 行:第二个示例生成一个 SVG 图像文件。如果创建 EAN13 对象时未指定 writer,则默认使用 SVG writer。
-
第 10–11 行:第三个示例再次创建一个 JPG 文件中的条形码,但这次会带有所谓的保护条(guard bars)。
如果需要在非标准尺寸下使用条形码,建议使用 SVG writer,因为矢量图像可以无损缩放。
以下是一个更复杂的示例:
1barcodeString = "20" + createRandomDigitString(10) 2print(barcodeString) 3 4myWriter = ImageWriter(format="PNG", mode="RGBA") 5 6opts = {"dpi": 200, 7 "module_width":0.5, 8 "module_height":10, 9 "background":(255, 255, 255, 0), 10 "foreground":(255, 0, 0, 255) 11 } 12 13with open('output/EAN13.png', 'wb') as f: 14 barcode = EAN13(barcodeString, writer=myWriter, guardbar=True) 15 barcodeImg = barcode.render(writer_options=opts) 16 barcodeImg.apply_transparency() 17 barcodeImg.save(f)
第 4 行:ImageWriter() 设置为以 RGBA 模式输出 PNG 图像(带透明度的 PNG)。
第 6–11 行:我们定义了一个名为 opts 的 Python 字典,用于设置若干参数。
-
首先,设置
dpi参数。我们将输出分辨率设为 200 DPI,而非默认的 300 DPI。 -
然后,通过
module_width和module_height调整条形码条块的宽度和高度。 -
最后,更改
background和foreground参数,实现红色条形码叠加在透明背景上的效果。
第 15–17 行:为了输出 EAN-13 条形码,我们对其进行渲染,应用透明度,然后保存。
以下是打印 40 个相同 EAN-13 条形码在一张 A4 胶贴标签纸上的示例。
该标签纸有 4 列 10 行胶贴标签。其他用于生成页面的设置如下:
| 毫米 | 像素 | |
|---|---|---|
| 宽度 | 45.7 | 540 |
| 高度 | 25.5 | 300 |
| 上边距 | 21 | 248 |
| 下边距 | 21 | 248 |
| 左边距 | 10.6 | 125 |
| 右边距 | 10.6 | 125 |
| 周围间距 | 0 | 0 |
| 横向间距 | 2 | 24 |
以下是一段代码,展示如何生成一张填满 40 个 EAN-13 条形码的 A4 页面:
1from barcode import EAN13 2from barcode.writer import ImageWriter 3from PIL import Image 4 5import random 6 7def createRandomDigitString(n): 8 return ''.join([str(random.randint(0,9)) for _ in range(n)]) 9 10barcodeString = "20" + createRandomDigitString(10) 11print(barcodeString) 12 13myWriter = ImageWriter(format="PNG") 14 15with open('output/EAN13.png', 'wb') as f: 16 barcode = EAN13(barcodeString, writer=myWriter, guardbar=True) 17 barcodeImg = barcode.render() 18 barcodeImg.save(f) 19 20with open('output/A4sheet.png', 'wb') as f: 21 img = Image.new(mode="RGB", size=(2481,3508), color=(255,255,255)) 22 img.save(f) 23 24def addBarcodesToImage(bgrImgPath, brcImgPath, pixw, pixh, rows, cols, gaparound, gapacross, sidemargin, tbmargin): 25 bgrImg = Image.open(bgrImgPath) 26 brcImg = Image.open(brcImgPath) 27 width, height = brcImg.size 28 29 for i in range(0, rows): 30 for j in range(0, cols): 31 coord = (sidemargin + (j*(pixw + gapacross)), tbmargin + (i*(pixh+gaparound))) # 标签左上角坐标 32 coord = (coord[0] + (pixw//2), coord[1] + (pixh//2)) # 标签中心点 33 coord = (coord[0] - (width//2), coord[1] - (height//2)) # 条形码图像在标签中的左上角坐标 34 bgrImg.paste(brcImg, coord) 35 return bgrImg 36 37im1 = "output/A4sheet.png" 38im2 = "output/EAN13.png" 39 40im_res = addBarcodesToImage(im1, im2, 540, 300, 10, 4, 0, 24, 125, 248) 41im_res.save("output/barcodesheet.png")
第 7–11 行:我们生成一个随机字符串,代表希望打印在 A4 纸上的 EAN13 条形码数据。
第 13 行:然后定义一个 ImageWriter,用于将条形码输出为 PNG 格式。
第 15–18 行:接下来,使用 EAN13 类创建 EAN13 条形码,通过 barcode.render() 渲染,并使用 save() 方法保存。
第 20–22 行:我们还创建了一个用于打印条形码的背景图像。这里使用 Image.new() 方法。尺寸设为 2481×3508 像素,这是 A4 页面在 300 DPI 下的大小。颜色设为白色。
第 24–35 行:为了在 A4 纸上多次打印条形码,我们需要一个函数来遍历相应位置并放置条形码。该函数名为 addBarcodesToImage()。
-
首先,使用
PIL库的Image.open()方法打开背景图像和条形码图像,然后获取条形码图像的宽度和高度。 -
接着,通过嵌套循环遍历行和列,计算每个条形码的正确坐标
coord。确定坐标后,使用paste()方法将条形码图像brcImg贴到背景图像bgrImg上。 -
最后,当 A4 纸被填满条形码后,返回更新后的背景图像
bgrImg。
第 39–40 行:这里 im1 和 im2 分别定义了背景图像和条形码图像的路径。
第 42 行:im_res 包含由 addBarcodesToImage() 函数输出的图像。
第 43 行:一旦获得 im_res 图像,即可使用 save() 方法将其保存。