Delphi 7和EMF+文件

3
我有一个应用程序,可以加载各种图形文件格式,例如bmp、jpg、png、emf等,并将它们渲染到屏幕上进行预览。
我正在使用Delphi 7。我刚刚了解到EMF+文件格式,它是在Windows XP时期创建的,利用了GDIPlus.dll。我可以使用Windows图片查看器打开EMF+文件,图像质量非常高,可以随意缩放而不会出现任何模糊。
问题是我无法找到一种方法(在Delphi 7中),以打开这个文件格式并在屏幕上呈现它。是否有人知道可以在Delphi 7中使用的代码示例或组件来呈现EMF+文件?
2个回答

4

TMetaFileCanvas不支持EMF+格式,但您可以使用GDI+完成您的任务。

以下是使用GDI+执行任务的示例代码:

type
  PGdiplusStartupInput = ^TGdiplusStartupInput;
  TGdiplusStartupInput = record
    GdiplusVersion: Integer;
    DebugEventCallback: Integer;
    SuppressBackgroundThread: Integer;
    SuppressExternalCodecs: Integer;
  end;

function GdiplusStartup(var Token: Integer; InputBuf: PGDIPlusStartupInput; OutputBuf: Integer): Integer; stdcall; external 'gdiplus.dll';
procedure GdiplusShutdown(Token: Integer); stdcall; external 'gdiplus.dll';
function GdipCreateFromHDC(DC: HDC; var Graphics: Integer): Integer; stdcall; external 'gdiplus.dll';
function GdipDeleteGraphics(Graphics: Integer): Integer; stdcall; external 'gdiplus.dll';
function GdipLoadImageFromFile(Filename: PWChar; var GpImage: Integer): Integer; stdcall; external 'gdiplus.dll';
function GdipDrawImageRect(Graphics, Image: Integer; X, Y, Width, Height: Single): Integer; stdcall; external 'gdiplus.dll';

procedure LoadEMFPlus(const FileName: WideString; DC: HDC; Width, Height: Integer);
var
  Token: Integer;
  StartupInput: TGdiplusStartupInput;
  Graphics: Integer;
  Image: Integer;
begin
  StartupInput.GdiplusVersion := 1;
  StartupInput.DebugEventCallback := 0;
  StartupInput.SuppressBackgroundThread := 0;
  StartupInput.SuppressExternalCodecs := 0;
  if GdiplusStartup(Token, @StartupInput, 0) = 0 then
  begin
    if GdipCreateFromHDC(DC, Graphics) = 0 then
    begin
      if GdipLoadImageFromFile(@FileName[1], Image) = 0 then
      begin
        GdipDrawImageRect(Graphics, Image, 0, 0, Width, Height);
      end;
      GdipDeleteGraphics(Graphics);
    end;
    GdiplusShutdown(Token);
  end;
end;

你可以这样调用它:

procedure TForm1.Button1Click(Sender: TObject);
begin
  LoadEMFPlus('EMFTest.emf',
    PaintBox1.Canvas.Handle, PaintBox1.Width, PaintBox1.Height);
end;

3
你可以使用支持EMF格式的"TMetaFileCanvas"。以下是代码片段:

procedure TForm1.Button1Click(Sender: TObject);
var  
  MyMetaFile: TMetaFile;  
  MyCanvas: TMetafileCanvas;
begin
  MyMetaFile:= TMetaFile.Create;
  try
    MyMetaFile.LoadFromFile('C:\example.emf');

    MyCanvas:= TMetafileCanvas.Create(MyMetaFile, 0);
    try
      MyCanvas.Draw(0, 0, MyMetaFile);
      MyCanvas.Pen.Color:= clRed;
      MyCanvas.MoveTo(0, 0);
      MyCanvas.LineTo(100, 100);
      MyCanvas.Free;

      Image1.Canvas.Draw(0, 0, MyMetaFile);
    finally
      MyCanvas.Free;
    end;

    MyMetaFile.SaveToFile('C:\example.emf');
  finally
    MyMetaFile.Free;
  end;
end;

通过这种方式,您可以加载EMF,绘制到EMF并保存它。但是在Delphi中将其呈现为矢量图形则是另一个问题。 Delphi默认情况下仅适用于位图图形。但据我所知,您只想读取和绘制它。例如,要将其转换为BMP,您可以执行以下操作:

// destroy canvas to transfer the image into the metafile object
FreeAndNil(MyCanvas);
// draw image as normal graphic
BMP.Canvas.Draw(0, 0, MyMetaFile);

编辑:

正如Marco所指出的那样,TMetaFileCanvas可能无法正确地使用EMF+。我没有测试过,所以无法确认。

但是似乎有一个可以使用的单元。

http://blog.synopse.info/post/2010/04/02/Antialiased-drawing-from-TMetaFile

下载链接如下:

http://synopse.info/files/SynGdiPlus.zip

我自己还没有检查过它,但看起来适合这个任务。


这只是普通的EMF,你确定它也支持EMF+吗?据我所知,Delphi在默认版本中没有GDIplus组件。 - Marco van de Voort
我不确定,但是Mitov Software的IGDI可能支持emf+。 IGDI是一个免费的开源Delphi库: http://www.mitov.com/html/download_igdi_.html - Logman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接