将 PDF 布局提取到图像而不改变 python 中的线宽

问题描述 投票:0回答:1

我正在开发一个项目,需要从最初从 AutoCAD 导出的 PDF 布局中提取图像。该布局包含详细的图纸,特别是太阳能模块的图纸,我需要这些 PNG 或 JPG 格式的图像。每次我尝试时,多边形(在本例中代表太阳能模块)都会更改或设置其线宽。

我尝试了几种方法和库(PyMuPDF、OpenCV、PIL、Pdf2image)。尽管尝试了不同的方法和库,但我还没有找到一种解决方案可以保持线宽在 AutoCAD 导出的 PDF 中的原始外观。

您可以从此链接下载 PDF:https://mega.nz/file/sx9XlSCQ#8Rj0qW5phaKkExvznX-RFGd4ySj4bp4kGOg6ZVF9aYU

这是我得到的结果:(微小线宽) enter image description here

这是预期的结果:(强线宽) enter image description here

我的问题是:

是否有一种方法或特定的库可以准确地从 AutoCAD 导出的 PDF 布局中提取图像,同时保留元素的原始外观?或者,是否有针对此特定问题的已知解决方法?

python pdf vector-graphics pymupdf rasterizing
1个回答
0
投票

正如评论中所讨论的,AutoCAD 导出已将这些对象的线宽设置为零。

引用 PDF 1.7 规范,第 8.4.3.2 节线宽,强调我的,

线宽 0 表示可以在设备分辨率下渲染的最细线:1 设备像素宽。然而,某些设备无法再现 1 像素线,并且在高分辨率设备上,它们几乎是不可见的。由于渲染此类零宽度线的结果取决于设备,因此不应使用它们

这篇 Autodesk 文章介绍了如何修复意外细或粗的线宽,但我们假设我们无法触及这些设置。

这个相当 hacky 的脚本使用 PyMuPDF 的低级函数 尝试将线宽命令修补为非零 - 我注意到文档中的其他对象使用线宽 6,所以这就是我在这里要做的。

import pymupdf

doc = pymupdf.open("Layout.pdf")

xreflen = doc.xref_length()
for xref in range(1, xreflen):
    if stream := doc.xref_stream(xref):
        if isinstance(stream, bytes):
            new_stream = stream.replace(b"S\n0 w\n", b"S\n6 w\n")
            if stream != new_stream:
                doc.update_stream(xref, new_stream)

doc.save("Layout_modified.pdf")

当我在修改后的文件中放大 macOS 预览时,蓝色面板不再总是细如发丝,而是有一些分量。光栅化修补后的文件可能会产生更好的结果。

© www.soinside.com 2019 - 2024. All rights reserved.