Save and load metafiles in a BLOB field without using DBImage

by Nov 25, 1997

 Question and Answer Database

FAQ878D.txt   Save and load metafiles in a BLOB field without using DBImage
Category   :VCL
Platform    :All
Product    :All 32 bit  

Question:
How can I save and load metafiles in a BLOB field without using the
DBImage component?


Answer:
The following example demonstrates saving metafile images to a
database as they exist on the disk, preserving any Placeable metafile
headers that may be present in the Metafile. The image is displayed
from the database in a TImage component.

Example:

unit Unit1;

interface

{$IFDEF WIN32}
  uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls, DBCtrls, Grids, DBGrids, Db,
      DBTables;
{$ELSE}
uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, DBTables, DB, Grids, DBGrids, ExtCtrls, StdCtrls;
{$ENDIF}

type
  TForm1 = class(TForm)
    Table1: TTable;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    Image1: TImage;
    Button1: TButton;
    Table1Name: TStringField;
    Table1WMF: TBlobField;
    OpenDialog1: TOpenDialog;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure DataSource1DataChange(Sender: TObject; Field: TField);
  private
    { Private declarations }
    FileName : string; {Used to hold a temp file name}
    procedure LoadWMFFromDatabase; {loads a WMF from the database}
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
 {Used for loading metafiles}
  OpenDialog1.Filter := 'Metafiles (*.wmf)|*.wmf';
  OpenDialog1.Options := [ofHideReadOnly, ofNoChangeDir];
  Image1.Stretch := true;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 {Erase the temp file if it exists}
  if FileName <> '' then
    DeleteFile(FileName);
end;

{This function gets a temporary file name form the system}
function GetTemporaryFileName : string;
{$IFNDEF WIN32}
  const MAX_PATH = 144;
{$ENDIF}
var
 {$IFDEF WIN32}
  lpPathBuffer : PChar;
 {$ENDIF}
  lpbuffer : PChar;
begin
 {Get the file name buffer}
  GetMem(lpBuffer, MAX_PATH);
 {$IFDEF WIN32}
 {Get the temp path buffer}
  GetMem(lpPathBuffer, MAX_PATH);
 {Get the temp path}
  GetTempPath(MAX_PATH, lpPathBuffer);
 {Get the temp file name}
  GetTempFileName(lpPathBuffer,
                  'tmp',
                  0,
                  lpBuffer);
 {Free the temp path buffer}
  FreeMem(lpPathBuffer, MAX_PATH);
 {$ELSE}
 {Get the temp file name}
  GetTempFileName(GetTempDrive('C'),
                  'tmp',
                  0,
                  lpBuffer);
 {$ENDIF}
 {Create a pascal string containg}
 {the  temp file name and return it}
  result := StrPas(lpBuffer);
 {Free the file name buffer}
  FreeMem(lpBuffer, MAX_PATH);
end;

procedure TForm1.LoadWMFFromDatabase;
var
  FileStream: TFileStream; {a temp file}
  BlobStream: TBlobStream; {the WMF Blob}
begin
  Image1.Picture.Metafile.Assign(nil);
 {Create a blob stream for the WMF blob}
  BlobStream := TBlobStream.Create(Table1WMF, bmRead);
  if BlobStream.Size = 0 then begin
   BlobStream.Free;
   Exit;
  end;
 {if we have a temp file then erase it}
  if FileName <> '' then
    DeleteFile(FileName);
 {Get a temp file name}
  FileName := GetTemporaryFileName;
 {Create a temp file stream}
  FileStream := TFileStream.Create(FileName,
                                   fmCreate or fmOpenWrite);
 {Copy the blob to the temp file}
  FileStream.CopyFrom(BlobStream, BlobStream.Size);
 {Free the streams}
  FileStream.Free;
  BlobStream.Free;
 {Dispaly the image}
  Image1.Picture.Metafile.LoadFromFile(FileName);
end;

{Save a wmf file to the database}
procedure TForm1.Button1Click(Sender: TObject);
var
  FileStream: TFileStream; {to load the wmf file}
  BlobStream: TBlobStream; {to save to the blob}
begin
 {Allow the button to repaint}
  Application.ProcessMessages;
  if OpenDialog1.Execute then begin
   {Turn off the button}
    Button1.Enabled := false;
   {Assign the avi file name to read}
    FileStream := TFileStream.Create(OpenDialog1.FileName,
                                     fmOpenRead);
    Table1.Edit;
   {Create a BlobStream for the field Table1WMF}
    BlobStream := TBlobStream.Create(Table1WMF, bmReadWrite);
   {Seek to the Begginning of the stream}
    BlobStream.Seek(0, soFromBeginning);
   {Delete any data that may be there}
    BlobStream.Truncate;
   {Copy from the FileStream to the BlobStream}
    BlobStream.CopyFrom(FileStream, FileStream.Size);
   {Free the streams}
    FileStream.Free;
    BlobStream.Free;
   {Post the record}
    Table1.Post;
   {Load the metafile in to a TImage}
    LoadWMFFromDatabase;
   {Enable the button}
    Button1.Enabled := true;
  end;
end;

procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
begin
  if (Sender as TDataSource).State = dsBrowse then
    LoadWMFFromDatabase;
end;

end.

7/16/98 4:31:28 PM
 

Article originally contributed by