2010-04-21 22 views
3

J'ai une application qui peut charger divers formats de fichiers graphiques tels que bmp, jpg, png, emf, etc ... et les rendre sur l'écran pour la prévisualisation. J'utilise Delphi 7. Je viens d'être présenté au format de fichier EMF + qui a été créé à l'époque de Windows XP qui est créé en utilisant le GDIPlus.dll. Je peux ouvrir les fichiers EMF + avec Windows Picture Viewer et l'image est très haute qualité et peut zoomer et dézoomer sans aucun flou.Delphi 7 et fichiers EMF +

Le problème est que je n'arrive pas à trouver un moyen (en Delphi 7) d'ouvrir ce format de fichier et de le restituer à l'écran. Est-ce que quelqu'un sait d'un échantillon de code ou d'un composant qui peut être utilisé dans Delphi 7 pour rendre un fichier EMF +?

Répondre

3

Vous pouvez utiliser un "TMetaFileCanvas" prenant en charge EMF. Un extrait de code:

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; 

De cette façon, vous pouvez charger EMF, dessiner sur EMF et l'enregistrer. Mais le présenter comme un graphique vectoriel de Delphi est un autre problème tout à fait. Delphi fonctionne uniquement avec les graphiques bitmap prêts à l'emploi. Mais si je comprends bien, vous voulez seulement lire et dessiner. Pour le convertir en BMP par exemple, vous pouvez faire:

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

EDIT:

Comme Marco aimablement fait remarquer TMetafileCanvas probablement le travail woun't correctement avec EMF +. Je n'ai pas testé cela donc je ne peux pas le confirmer.

Mais il semble y avoir une unité qui fonctionne avec ça.

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

téléchargement est disponible à partir de:

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

Havent vérifié moi-même, mais il semble approprié pour le travail.

+0

C'est bon vieux EMF, êtes-vous sûr qu'il fait aussi EMF + ? Afaik Delphi n'a pas de composants GDIplus dans la distribution d'actions –

+0

Hm, non je ne suis pas sûr :) – Runner

+0

Mis à jour la réponse. – Runner

4

TMetaFileCanvas ne fonctionnera pas correctement avec EMF + mais votre tâche peut être accomplie en utilisant GDI +.

Voici quelques exemples de code qui montre comment le faire en utilisant 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; 

Et vous pouvez l'appeler comme ceci:

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