【发布时间】:2016-03-19 18:24:54
【问题描述】:
我正在创建一些 .wmf 文件,但其中一些似乎已损坏并且无法在任何图元文件查看器中显示。经过反复试验,我发现问题是由它们的尺寸引起的。如果我将同一张图按比例缩放以减小尺寸,它将显示出来。
现在,我想知道绘图的大小是否有限制,或者问题是否出在其他地方。我知道这些文件have a 16-bit data structure,所以我猜每个维度的限制是 2 ^ 16 个单位,(如果已签名,则为 2 ^ 15)。但在我的测试中,它大约是 25,000。所以我不能依赖这个值,因为限制可以是任何东西(宽度*高度可能,或者绘图的分辨率可能会影响它)。我找不到有关描述此内容的 .wmf 文件的可靠资源。
这是显示问题的示例代码:
procedure DrawWMF(const Rect: TRect; const Scale: Double; FileName: string);
var
Metafile: TMetafile;
Canvas: TMetafileCanvas;
W, H: Integer;
begin
W := Round(Rect.Width * Scale);
H := Round(Rect.Height * Scale);
Metafile := TMetafile.Create;
Metafile.SetSize(W, H);
Canvas := TMetafileCanvas.Create(Metafile, 0);
Canvas.LineTo(W, H);
Canvas.Free;
Metafile.SaveToFile(FileName);
Metafile.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
const
Dim = 40000;
begin
DrawWMF(Rect(0, 0, Dim, Dim), 1.0, 'Original.wmf');
DrawWMF(Rect(0, 0, Dim, Dim), 0.5, 'Scaled.wmf');
try
Image1.Picture.LoadFromFile('Original.wmf');
except
Image1.Picture.Assign(nil);
end;
try
Image2.Picture.LoadFromFile('Scaled.wmf');
except
Image2.Picture.Assign(nil);
end;
end;
PS:我知道将 Metafile.Enhanced 设置为 True 并将其保存为 .emf 文件可以解决问题,但我为其生成文件的目标应用程序并没有支持增强的元文件。
编辑: 正如下面的答案中提到的,这里有两个不同的问题:
主要问题在于文件本身,它在每个维度上都有 2^15 的限制。如果绘图的宽度或高度超过此值,delphi 将写入损坏的文件。您可以在Sertac's answer找到更多详细信息。
第二个问题是关于在TImage 中加载文件。当您想在 delphi VCL 应用程序中显示图像时,还有另一个限制。这个是系统相关的,并且与要在其上绘制绘图的 DC 的 dpi 相关。 Tom's answer 对此进行了详细描述。将 0.7 作为 Scale 传递给 DrawWMF(上面的代码示例)在我的 PC 上重现了这种情况。生成的文件没问题,可以用其他图元文件查看器(我使用MS Office 图片管理器)查看,但是VCL无法显示,但是加载文件时没有引发异常。
【问题讨论】:
-
我重新标记为 winapi,因为我相信这是关于 WMF 格式的问题,而不是与 Delphi 相关的任何问题。
-
您确定您的限制在 25000 左右吗?准确地说,它可能是 32767 吗?
-
根据总面积(宽度×高度),这似乎是内存分配失败。