【问题标题】:Delphi 7 and EMF+ filesDelphi 7 和 EMF+ 文件
【发布时间】:2011-02-10 17:55:55
【问题描述】:

我有一个应用程序,它可以加载各种图形文件格式,例如 bmp、jpg、png、emf 等...并将它们渲染到屏幕上进行预览。

我使用的是 Delphi 7。我刚刚了解了 EMF+ 文件格式,它是在 Windows XP 时代创建的,它是使用 GDIPlus.dll 创建的。我可以用 Windows 图片查看器打开 EMF+ 文件,图像质量非常好,可以放大和缩小,完全没有任何模糊。

问题是我似乎找不到方法(在 Delphi 7 中)打开此文件格式并将其呈现在屏幕上。有谁知道可以在 Delphi 7 中用于呈现 EMF+ 文件的代码示例或组件?

【问题讨论】:

    标签: delphi gdi+ delphi-7 render .emf


    【解决方案1】:

    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;
    

    【讨论】:

      【解决方案2】:

      您可以使用支持 EMF 的“TMetaFileCanvas”。一个代码sn-p:

      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+ 吗? Afaik Delphi 在股票发行版中没有 GDIplus 组件
      • 我不确定,但 Mitov Software 的 IGDI 可能支持 emf+ IGDI 是一个免费的开源 Delphi 库:mitov.com/html/download_igdi_.html
      猜你喜欢
      • 1970-01-01
      • 2012-10-01
      • 2012-08-08
      • 1970-01-01
      • 2014-10-22
      • 2011-05-17
      • 1970-01-01
      • 2010-09-12
      • 1970-01-01
      相关资源
      最近更新 更多