从EMF图像文件中提取宽度/高度尺寸

时间:2010-08-02 19:28:03

标签: windows perl vector-graphics .emf

我维护了一个小的Perl库,可以从图像中提取宽度/高度,适用于那些需要该功能但不使用更大,更通用的库的人。我被问到是否可以支持Windows EMF格式。但是,我试图找到一个很好的格式规范,或者更好的示例代码(用任何语言),我没有太多运气。我正在寻找格式上不错的规范,或者阅读/解析文件的例子。通常,并且非常感谢所有帮助。

2 个答案:

答案 0 :(得分:7)

官方规范可以直接从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 - leftheight = bottom - top

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

答案 1 :(得分: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