dwg 文件数据结构
在文件的第13位到16位的四个字节,保存预览图像数据的起地址(示例值:58 00 00 00),从该地址起,数据主要构成为如下表:
地址属性 | 地址 | 长度 | 示例数值 | 说明 |
---|---|---|---|---|
SN(start sentinel) | 58-67 | 16 | 1F 25 6D 07 D4 36 28 28 9D 57 CA 3F 9D 44 10 2B | 图像数据开始标志,16字节常值,不会改变,否则表示文件损坏。 |
oversize | 68-6B | 4 | AB 4D 00 00 | 数据的总长度,包括从type到BMP/WMF data 末的地址长度 |
type | 6C | 1 | 02 | 图像的类型02-BMP;03-WMF,就两种;这里示例值是02,没有03数据。 |
header code | 6D | 1 | 01 | 图像文件头代码,必是01 |
header address | 6E-71 | 4 | 7F 00 00 00 | 图像文件头起地址 |
header size | 72-75 | 4 | 50 00 00 00 | 图像文件头数据长度 |
data code | 76 | 1 | 02/03 | 图像BMP/WMF代码 |
data address | 77-7A | 4 | CF 00 00 00(7F+50=CE) | 图像BMP/WMF数据起地址 |
data size | 7B-7E | 4 | 48 4D 00 00 | 图像BMP/WMF数据长度 |
header data | 7F-CE | 50 | ...... | 图像文件头数据,长度源于header size |
BMP/WMF data | CF-4D16 | 4D48 | ...... | 图像BMP/WMF数据,长度源于data size |
EN | 4D17-4E26 | 10 | E0 DA 92 F8 2B C9 D7 D 7 62 AB 35 C0 62 BB EF D4 | 结束16字节,常值 |
python3 读取文件缩略图
# coding:utf-8
import io
from PIL import Image
import struct
# ================= #
# dwg 文件缩略图提取 #
# ================= #
def read_fmt(fmt, fp):
fmt_size = struct.calcsize(fmt)
data = fp.read(fmt_size)
try:
assert len(data) == fmt_size, 'read=%d, expected=%d' % (len(data), fmt_size)
except AssertionError:
fp.seek(-len(data), 1)
raise
return struct.unpack(fmt, data)
def thumbnail(filePath, savePath):
with open(filePath, 'rb') as fd:
fd.seek(13, 0)
pos_sentinel = read_fmt('I', fd)[0] # I 表示读取4个字节整数
fd.seek(pos_sentinel+26, 0)
header_size = read_fmt('I', fd)[0]
fd.seek(5, 1)
data_size = read_fmt('I', fd)[0]
fd.seek(header_size, 1)
png_data = fd.read(data_size)
print(header_size, data_size)
if data_size != len(png_data):
raise Exception("dwg 解析错误!")
imgio = io.BytesIO(png_data)
with Image.open(imgio) as image:
image.save(savePath, 'PNG')
if __name__ == "__main__":
thumbnail('/Users/xx/claw.dwg', '/Users/xxx/dwgpic2.png')