如何用Python生成带矢量条码的PDF并读码?

前言

PDF(Portable Document Format,便携式文档格式)是由Adobe开发的用于呈现文档的文件格式。基于PostScript语言,每个PDF文件都封装了固定布局平面文档的完整描述,包括文本、字体、矢量图形、光栅图像和显示它所需的其他信息。

条码是一种以视觉、机器可读的形式表示数据的方法。它可以存储为光栅图像或矢量图形,并保存在PDF中。

作为图像存在PDF中的条码比较常见,而关于PDF中矢量条码的文章不多。因此,在本文中,我们将讨论如何用Python生成带矢量条码的PDF并从中读取条码

Dynamsoft Barcode Reader会被用于读取条码。由于我们可以直接获得矢量条码的黑条或白条的坐标,因此从矢量图形解码的性能和准确性会优于从光栅图像解码。

文末领取Python全套最新学习资源

生成条码并将其保存为SVG

有许多条码生成的库,但可以将条码作为矢量图形导出为SVG的库并不多。在这里,我们使用Python的python-barcode库来执行此操作。

使用以下代码生成Code128格式的条码:

from barcode import Code128
from barcode.writer import SVGWriter
code1 = Code128("Code 128", writer=SVGWriter())
code1.save("out.svg")

在PDF页面中嵌入矢量条码

接下来,我们将把矢量条码图形嵌入到PDF中。

我们可以使用Adobe Illustrator和Inkscape等矢量设计工具来实现这一点。

Inkscape的屏幕截图:

inkscape.jpg

我们也可以用代码生成PDF。这里,我们使用Python及其fpdf2库来实现这一点。

from io import BytesIO
from fpdf import FPDF
from barcode import Code128
from barcode.writer import SVGWriter

# Create a new PDF document
pdf = FPDF()
pdf.add_page()

pdf.set_font("helvetica", "B", 16)
pdf.cell(40, 10, "A PDF page with Code128 barcodes.")

# Generate a Code128 barcode as SVG:
svg_img_bytes = BytesIO()
code1 = Code128("Code 128", writer=SVGWriter())
code1.write(svg_img_bytes)
pdf.image(svg_img_bytes, x=10, y=50, w=100, h=70)

# Generate a second Code128 barcode as SVG:
svg_img_bytes = BytesIO()
code2 = Code128("Second Code 128", writer=SVGWriter())
code2.write(svg_img_bytes)
pdf.image(svg_img_bytes, x=10, y=120, w=100, h=70)

# Output a PDF file:
pdf.output('code128_barcode.pdf')

从PDF文件读取条码

大多数条码读取的库只能处理光栅图像。因此,在读取条码之前,我们必须将PDF页面渲染为图像。

但实际上,我们可以直接解析矢量条码图形进行解码。

例如,我们可以使用PyMuPDFget_drawings方法读取图形的信息。

>>> import fitz
>>> doc = fitz.open("vector.pdf")
>>> doc[0].get_drawings()
[{'items': [('re', Rect(28.34600067138672, 141.72999572753906, 365.26654052734375, 436.3016357421875), -1)], 'type': 'f', 'even_odd': False, 'fill_opacity': 1.0, 'fill': (1.0, 1.0, 1.0), 'rect': Rect(28.34600067138672, 141.72999572753906, 365.26654052734375, 436.3016357421875), 'seqno': 1, 'layer': '', 'closePath': None, 'color': None, 'width': None, 'lineCap': None, 'lineJoin': None, 'dashes': None, 'stroke_opacity': None}, {'items': [('re', Rect(52.604278564453125, 150.07992553710938, 56.42462158203125, 275.33087158203125), -1)], 'type': 'f', 'even_odd': False, 'fill_opacity': 1.0, 'fill': (0.0, 0.0, 0.0), 'rect': Rect(52.604278564453125, 150.07992553710938, 56.42462158203125, 275.33087158203125), 'seqno': 2, 'layer': '', 'closePath': None, 'color': None, 'width': None, 'lineCap': None, 'lineJoin': None, 'dashes': None, 'stroke_opacity': None}]

Dynamsoft Barcode Reader能够读取PDF中的矢量条码。此功能默认启用。

以下是从PDF中读取条码的代码(需要申请一个许可证才能使用它):

from dbr import *
error = BarcodeReader.init_license("license")
if error[0] != EnumErrorCode.DBR_OK:
    # Add your code for license error processing
    print("License error: "+ error[1])
reader = BarcodeReader()
results = reader.decode_file("code128_barcode.pdf")
if results != None:
    i = 0
    for text_result in results:
        print("Barcode " + str(i))
        print("Barcode Format : " + text_result.barcode_format_string)
        print("Barcode Text : " + text_result.barcode_text)
        i = i+1

可以通过更新其与PDF相关的运行时设置来变更其行为。

settings = reader.get_runtime_settings()
settings.pdf_reading_mode = EnumPDFReadingMode.PDFRM_VECTOR
reader.update_runtime_settings(settings)

读取模式可以设置为以下值:

  • EnumPDFReadingMode.PDFRM_RASTER:将PDF渲染为光栅图像以进行解码
  • EnumPDFReadingMode.PDFRM_VECTOR:直接读取矢量条码
  • EnumPDFReadingMode.PDFRM_AUTO:如果PDF包含矢量条码,则使用矢量模式

矢量模式的识别速度比光栅模式更快:

Time elapsed decoding a PDF file:
Vector mode: 15.6253ms.
Raster mode: 84.721ms.

但由于矢量模式仅适用于1D条形码,如果要读取二维码(如QR码),则需要使用光栅模式。

确定PDF是否为矢量PDF

让我们讨论另一个问题:如何确定PDF是否为矢量PDF。

正如我们所知,PDF包含光栅图像、矢量图形或文本。

因此,如果PDF页面包含文本或矢量图形,它就是矢量PDF。

我们可以使用以下代码进行检测:

import fitz

doc = fitz.open("merged.pdf")

index = 0
for page in doc:
    index = index + 1
    has_text = False
    has_images = False
    has_vector_graphics = False
    if len(page.get_images()) > 0:
        has_images = True
    if page.get_text() != "":
        has_text = True
    if len(page.get_drawings()) > 0:
        has_vector_graphics = True

    if has_images and has_text == False and has_vector_graphics == False:
        print("Page "+str(index)+" is raster")
    elif has_vector_graphics or has_text:
        print("Page "+str(index)+" is vector")

以上就是今天的全部内容分享,觉得有用的话欢迎点赞收藏哦!

Python经验分享

学好 Python 不论是用于就业还是做副业赚钱都不错,而且学好Python还能契合未来发展趋势——人工智能、机器学习、深度学习等。
小编是一名Python开发工程师,自己整理了一套最新的Python系统学习教程,包括从基础的python脚本到web开发、爬虫、数据分析、数据可视化、机器学习等。如果你也喜欢编程,想通过学习Python转行、做副业或者提升工作效率,这份【最新全套Python学习资料】 一定对你有用!

小编为对Python感兴趣的小伙伴准备了以下籽料 !

对于0基础小白入门:

如果你是零基础小白,想快速入门Python是可以考虑培训的!

  • 学习时间相对较短,学习内容更全面更集中
  • 可以找到适合自己的学习方案

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、机器学习、Python量化交易等学习教程。带你从零基础系统性的学好Python!

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

二、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

五、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。


最新全套【Python入门到进阶资料 & 实战源码 &安装工具】(安全链接,放心点击)

我已经上传至CSDN官方,如果需要可以扫描下方官方二维码免费获取【保证100%免费】

*今天的分享就到这里,喜欢且对你有所帮助的话,记得点赞关注哦~下回见 !

  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值