2010-04-21 2 views
3

У меня есть приложение, которое может загружать различные графические форматы файлов, такие как bmp, jpg, png, emf и т. Д., И отображать их на экране для предварительного просмотра.Файлы Delphi 7 и EMF +

Я использую Delphi 7. Я только что познакомился с файлом формата EMF +, который был создан во время Windows XP, созданного с использованием GDIPlus.dll. Я могу открыть файлы EMF + с помощью Windows Picture Viewer, и изображение очень высокое, и может увеличиваться и уменьшаться без какого-либо размытия.

Проблема заключается в том, что я не могу найти способ (в Delphi 7), чтобы открыть этот формат файла и отобразить его на экране. Кто-нибудь знает образец кода или компонент, который может использоваться в Delphi 7 для рендеринга файла EMF +?

ответ

3

Вы можете использовать «TMetaFileCanvas» с поддержкой EMF. Фрагмент кода:

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); 

EDIT:

Как Марко любезно указал TMetaFileCanvas вероятно woun't корректно работают с EMF +. Не проверял, поэтому я не могу это подтвердить.

Но, похоже, есть единица, которая работает с этим.

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

Загрузка доступна:

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

Havent проверил это сам, но это выглядит подходящим для работы.

+0

Это простой старый EMF, вы уверены, что это также делает EMF + ? Afaik Delphi не имеет компонентов GDIplus в складе distro –

+0

Хм, нет, я не уверен :) – Runner

+0

Обновлен ответ. – Runner

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;