2

我维护了一个小型 Perl 库,可以从图像中提取宽度/高度,供那些想要该功能而不使用更大、更通用的库的人使用。有人问我是否可以支持 Windows EMF 格式。但是,我的 Google-fu 在尝试找到一个好的格式规范或更好的示例代码(任何语言)时,我的运气并不好。我正在寻找一个体面的格式规范,或读取/解析文件的示例。像往常一样,非常感谢所有帮助。

4

2 回答 2

11

官方规范可以直接从 MSDN 下载,网址为http://msdn.microsoft.com/en-us/library/cc230514(PROT.10).aspx

阅读和理解需要一些时间,但如果您以前使用过二进制文件格式,这绝对是可行的。

但请注意,EMF 是一种(伪)矢量图像格式,因此图像可以缩放到任意大小。但可能有默认的宽度和高度。特别是,确实应该有一个明确定义的纵横比。

更新

认为元文件的宽度(以像素为单位)是文件的第 5 个基数,而高度(以像素为单位)是第 6 个基数。在一个典型的案例中。至少这对您来说可能是一个不错的起点。

我刚刚创建了一个示例 EMF 文件,它开始

01 00 00 00 88 00 00 00 00 00 00 00 00 00 00 00
ae 01 00 00 75 01 00 00 00 00 00 00 00 00 00 00

第五个基数是AE010000,由于字节小端,十六进制为000001AE,即十进制为430。第六个基数是 75010000,即十六进制的 00000175 或十进制的 373。因此我得到的尺寸是 430×373 平方像素。Paint 报告 432×374 平方像素。

如果我有更多的时间,我会更广泛地研究文件格式。但至少我希望这可能是你的起点。

更新 2

第三个和第四个 32 位整数显然是图像的左坐标和上坐标,分别以逻辑单位表示,而第五个和第六个 32 位整数是右坐标和下坐标。在大多数情况下(top, left) = (0, 0),然后我上面的文字是正确的(即width = rightheight = top坐标)。

如果(top, left) <> (0, 0),那么,自然,width = right - left并且height = bottom - top

现在这可能不是全部。如果您将获得的数字与 Paint 报告的数字进行比较,您会得到小的偏差。所以待续......

于 2010-08-02T19:42:17.580 回答
0

根据 Andreas Rejbrand 的研究,我用 Python 编写了获取 EMF 文件大小的代码:

with open("img.emf", "rb") as f:
    f.read(16)
    w1, w2 = f.read(1).hex(), f.read(1).hex()
    f.read(2)
    h1, h2 = f.read(1).hex(), f.read(1).hex()

width  = int(str(w2) + str(w1), 16) * 762 # I've no idea why is '762' but it works this way
height = int(str(h2) + str(h1), 16) * 762

我相信如果它能够读取字节,它也可以在 Perl 中实现。

以下是它在实际任务中的工作方式:Unable to insert EMF into Word using Python

于 2021-05-26T12:53:27.787 回答