Delphi 7 和 EMF+文件

发布于 2024-08-29 22:20:30 字数 296 浏览 6 评论 0原文

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

我使用的是 Delphi 7。我刚刚了解了 EMF+ 文件格式,该格式是在 Windows XP 左右创建的,是利用 GDIPlus.dll 创建的。我可以使用 Windows 图片查看器打开 EMF+ 文件,图像质量非常高,可以放大和缩小,一点也不模糊。

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

I have an application that can load various graphical file formats such as bmp, jpg, png, emf, etc... and render them onto the screen for previewing.

I am using Delphi 7. I have just been introduced to the EMF+ file format that was created around the time of Windows XP that is created utilizing the GDIPlus.dll. I can open the EMF+ files with Windows Picture Viewer and the image is very high quaility and can zoom in and out without any blurring at all.

The problem is I can't seem to find a way (in Delphi 7) to open this file format and render it on the screen. Does anyone know of a code sample or component that can be used in Delphi 7 to render an EMF+ file?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

傲鸠 2024-09-05 22:20:30

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;

TMetaFileCanvas won't work correctly with EMF+ but your task can be completed using GDI+.

Here's some sample code that demonstrates how to do it using 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;

And you can call it like this:

procedure TForm1.Button1Click(Sender: TObject);
begin
  LoadEMFPlus('EMFTest.emf',
    PaintBox1.Canvas.Handle, PaintBox1.Width, PaintBox1.Height);
end;
少钕鈤記 2024-09-05 22:20:30

您可以使用具有 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

我自己还没有检查过,但它看起来适合这项工作。

You can use a "TMetaFileCanvas" that has EMF support. A code snippet:

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;

This way you can load EMF, draw to EMF and save it. But presenting it as a vector graphics from Delphi is another problem altogether. Delphi only works well with bitmap graphics out of the box. But as I understand you only want to read and draw it. To convert it to BMP for instance you can do:

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

EDIT:

As Marco kindly pointed out TMetaFileCanvas probably woun't work correctly with EMF+. Haven't tested that so I can't confirm it.

But there seems to be a unit that works with that.

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

Download is available from:

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

Havent checked it out myself, but it looks appropriate for the job.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文