Images in a database

I would like to a database to have a person's details and their photo. How do I link each photo to a field in the database. Someone talked of BLOB fileds and I have no idea how it is done. Please help!
LVL 11
Goodangel MatopeSoftware ArchitectAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

kretzschmarCommented:
what database?
0
Goodangel MatopeSoftware ArchitectAuthor Commented:
Paradox (I presume that comes default with Delphi 4)

0
CesarioCommented:
To load a new Picture just use :

DbImage1.Picture.LoadFromFile ('C:\xxx.bmp');

Best Regards

Cesario
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

kretzschmarCommented:
which image-formats u will use?
0
Goodangel MatopeSoftware ArchitectAuthor Commented:
I would like to use jpegs, and tiffs if possible (tiff for image of identification card.)
0
kretzschmarCommented:
well, from my paq

first the bad news,
you cannot use the graphic-fieldtyp for jpeg-images, also you can't use the
tdbimage-component for visualzing the image.

the soloution:

a sample

first in the paradox structure the BlobField is type Binary
and now follows a sample-unit,
which stores and get the JPeg

unit db_pict_u;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Db, DBTables, ExtCtrls, DBCtrls, StdCtrls, Mask, Menus, jpeg; // JPeg unit is used

type
  TForm1 = class(TForm)
    DBEdit1: TDBEdit;   // A other DBField
    DBNavigator1: TDBNavigator;
    Table1: TTable;
    DataSource1: TDataSource;
    PopupMenu1: TPopupMenu;     // a Popup linked to Image1
    LoadPicture1: TMenuItem;    // the MenuItem of the Popup
    OpenDialog1: TOpenDialog;   // OpenDialog
    Image1: TImage;             // Visual Output for the JPeg
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure LoadJPEG1Click(Sender: TObject);      // File Load and Store in DB
    procedure Table1AfterScroll(DataSet: TDataSet); // Get JPeg and Display in Image1
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  JPegImage : TJpegImage;  //A temporary JPeg-Object

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  JpegImage := TJPegImage.Create; // Create JPeg-Object
  Table1.Open;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Table1.Close;
  JPegImage.Free;  // Free JPeg-Object
end;

procedure TForm1.LoadJPEG1Click(Sender: TObject);
Var
  MyBlobStream : TBlobStream;      // Streams
  MyJPegStream : TMemoryStream;
begin
  if (Table1.State = dsEdit) or
     (Table1.State = dsInsert) then    // Do only if in edit mode
  begin
    If opendialog1.Execute then    // If file selected
    begin
      if Table1.FieldByName('Bild2').IsBlob then   // this line can deleted
      begin
        MyJPegStream := TMemoryStream.Create;      // Handle JPegFile
        JPegImage.LoadFromFile(opendialog1.filename);
        JPegImage.SaveToStream(MyJPegStream);
        // Prepare Blob
        MyBlobStream :=
TBlobStream.Create(TBlobField(Table1.FieldByName('Bild2')),bmReadWrite);
        MyBlobStream.CopyFrom(MyJPegStream,0);  // Copy JPeg into BlobField
        Image1.Picture.Assign(JPegImage);  // Display
        MyJPegStream.Free;  //Free all
        MyBlobStream.Free;
      end;
    end;
  end else ShowMessage('Table is not in Edit Mode!');
end;

procedure TForm1.Table1AfterScroll(DataSet: TDataSet);
Var
  MyBlobStream : TBlobStream;
begin
  // Do Only if a JPeg available
  if (Table1.FieldByName('Bild2').IsBlob) and (not(Table1.FieldByName('Bild2').IsNull)) then
  begin
    // Prepare Streams
    MyBlobStream :=
TBlobStream.Create(TBlobField(Table1.FieldByName('Bild2')),bmRead);
    JPegImage.LoadFromStream(MyBlobStream);
    Image1.Picture.Assign(JPegImage);  //Display JPeg
    MyBlobStream.Free;  // Free Stream
  end
  else image1.Picture := Nil;  // No JPeg saved disable display
end;

end.

meikl
0
kretzschmarCommented:
just to remark,

its just a sample,
therefore i've no try..except, try..finally
blocks inserted, which should be done for daus (users, which are not carefull)

meikl
0
Goodangel MatopeSoftware ArchitectAuthor Commented:
Does that mean I cannot save to the BLOB field? How will I access the same image again in future?
0
kretzschmarCommented:
?,

you can access and replace/save the jpeg-image in the blob-field as described above, you can also get it back to a file (this method is not included in the sample above, but it isn't difficult)

meikl
0
CesarioCommented:
Hi,

An Artikel:Using Jpegs with Paradox

http://www.delphi3000.com/article.asp?ID=1315

Best Regards Cesario
0
kretzschmarCommented:
well cesario,
but this article is just not complete,
because if you use table.fieldname as the author mentioned
you will have a tfield, and then you must do an additional conversion to tblobfield to get access to the streaming capabilities.

but at least its just the same as my sample

meikl
0
kretzschmarCommented:
sorry cesario,

didn't read the beginning of the article exactly,
where the author explains to create persistant fields.

well with persistant fields the code in the article will work also

meikl ;-)
0
kretzschmarCommented:
any problems, goodangel?
0
kretzschmarCommented:
goodangel, are you alive?
0
Goodangel MatopeSoftware ArchitectAuthor Commented:
Hie Kretzschmar. I am alive and I am wondering if I can also use tiffs. I tried the stuff above and I have not managed to get it to work. I will accept your answer though. Will tiffs work in a paradox database?

0
kretzschmarCommented:
hi goodangel,

glad to hear, that you're alive :-)

Tiff will work
in the main manner,
but you will need a tiff-object like the jpeg-object for the visualizing from a third partydevelopment, because tiff is not included with delphi.

take a look to
http://www.torry.ru/vcl/graphics/packs/tiffpack.zip

i've a sample-app for jpg, which i can send you, if you leave your email address here.

and points only, if you get it work

meikl ;-)
0
kretzschmarCommented:
>in the main manner,
should be read:
in the same manner,

meikl :-)
0
Goodangel MatopeSoftware ArchitectAuthor Commented:
Meikl

My email is goodangelma@ncr.co.zw

Please email the sample app. I will be most obliged.
0
kretzschmarCommented:
hi goodangel,

sorry for delay, but i played a bit with mike lischke's graphicEx,
which is also available to handle tiff and various other formats

its free for noncomercial use at www.lischke-online.de

i send you this demo-app and a sample table
(in this demo-app you can store and restore any file,
additional is tried to show the file-/blobcontent as image)

unit db_picture_u;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, Forms, Dialogs,
  ExtDlgs, Db, DBTables, ExtCtrls, DBCtrls, StdCtrls, Mask, ComCtrls,
  GraphicEx, Graphics;

type
  TForm1 = class(TForm)  //db-navigation
    Table1: TTable;              //the table, where the images are stored
    DataSource1: TDataSource;
    Panel1: TPanel;
    ProgressBar1: TProgressBar;
    DBNavigator1: TDBNavigator;
    Button1: TButton;
    Panel2: TPanel;
    DBEdit1: TDBEdit;
    DBEdit2: TDBEdit;
    Label1: TLabel;
    Label2: TLabel;
    Table2: TTable;
    ScrollBox1: TScrollBox;
    Image1: TImage;
    Button2: TButton;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    procedure Button1Click(Sender: TObject); //execute load and preStore to the Blobfield
    procedure FormCreate(Sender: TObject);   //TableOpen
    procedure FormDestroy(Sender: TObject);  //TableClose
    procedure Table1AfterScroll(DataSet: TDataSet);
    procedure Table1BeforeScroll(DataSet: TDataSet);
    procedure Image1Progress(Sender: TObject; Stage: TProgressStage;
      PercentDone: Byte; RedrawNow: Boolean; const R: TRect;
      const Msg: String);
    procedure Table1AfterInsert(DataSet: TDataSet);
    procedure Table1BeforePost(DataSet: TDataSet);
    procedure Button2Click(Sender: TObject);
  private
    Function DisplayImage(AStream : TStream; AExtension : String) : Boolean;
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

Function TForm1.DisplayImage(AStream : TStream; AExtension : String) : Boolean;
Var
  //Extended Graphicformats
  AExGraphicClass: TGraphicExGraphicClass;
  AExGraphic: TGraphicExGraphic;
  //Standard Graphicformats
  AGraphicClass : TGraphicClass;
  AGraphic : TGraphic;
  OldPosition : Integer;
begin
  Result := False;  //do as that cannot be loaded
  If Assigned(AStream) then
  try
    OldPosition := AStream.Position;
    try
      AStream.Position := 0;  //Remember Streams Position
      //Check for Extended Graphicformats
      AExGraphicClass := GraphicEx.FileFormatList.GraphicFromContent(AStream);
      if AExGraphicClass <> Nil then
      begin
        AExGraphic := AExGraphicClass.Create;
        try
          //Load Extended Graphicformats
          AExGraphic.LoadFromStream(AStream);
          Image1.Picture.Graphic := AExGraphic;
          Result := True;
        finally
          AExGraphic.Free;
        end;
      end
      else
      begin
        //Check for Standard Graphicformats
        AGraphicClass := GraphicEx.FileFormatList.GraphicFromExtension(AExtension);
        if AGraphicClass <> Nil then
        begin
          AGraphic := AGraphicClass.Create;
          try
            //Load Standard Graphicformats
            AGraphic.LoadFromStream(AStream);
            Image1.Picture.Graphic := AGraphic;
            Result := True;
          finally
            AGraphic.Free;
          end;
        end;
      end;
    finally
      AStream.Position := OldPosition;
    end;
  except
    Raise;
  end;
end;

//Load any file into the BlobField
procedure TForm1.Button1Click(Sender: TObject);
Var
  ExtS : String;  //Holds The Extension
begin
  if (Table1.State = dsEdit) or
     (Table1.State = dsInsert) then    // Do only if in edit mode
  begin
    If opendialog1.Execute then    // If file selected
    begin
      if Table1.FieldByName('Picture').IsBlob then   // this line can deleted
      begin  //remember the Extension
        ExtS := copy(AnsiUpperCase(ExtractFileExt(OpenDialog1.FileName)),2,MaxLongInt);
        try
          TBlobField(Table1.FieldByName('Picture')).LoadFromFile(opendialog1.filename);  //Store the File in the Blob
          Table1.FieldByName('Typ').AsString := ExtS; //Store the Extension in the Grafic-TypField
          try
            //try to load Image, also from file
            image1.Picture.LoadFromFile(opendialog1.filename);
          except
            //failed to load Image, also from file
            showmessage('Cannot display this File as Imageformat'+#10+
                        'File is loaded anyway');
            image1.Picture := Nil;
          end;
        except
          //Any Error
          Raise;
        end;
      end;
    end;
  end else ShowMessage('Table is not in Edit Mode!');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  //some prepare
  Opendialog1.Filter :=
    GraphicEx.FileFormatList.GetGraphicFilter([],fstBoth,[foIncludeAll,foIncludeExtension],nil);
  Opendialog1.Options := [ofFileMustExist,ofEnableSizing];
  Table1.Open;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  //some unprepare
  Table1.Close;
end;

//After Scrolling the TableCursor
procedure TForm1.Table1AfterScroll(DataSet: TDataSet);
Var
  AStream : TMemoryStream;
begin
  try
    try
      // Do Only if a Picture available
      if (Table1.FieldByName('Picture').IsBlob) and
         (not(Table1.FieldByName('Picture').IsNull)) then
      begin  //create a stream
        AStream := TMemoryStream.Create;
        try
          //Store the BlobContent into the Stream
          TBlobField(Table1.FieldByName('Picture')).SaveToStream(AStream);
          //Try to Display the image
          if not DisplayImage(AStream,Table1.FieldByName('Typ').AsString) then
          begin
             //Failed to Display the image
            image1.Picture.assign(Nil);
            showmessage('Cannot display this File as Image');
          end;
        finally
          AStream.Free;  // Free Stream
        end;
      end
      else image1.Picture.assign(Nil);  // No Picture saved disable display
    Finally
      //Restore Cursor
      screen.Cursor := crDefault;
      ProgressBar1.Position := 100;
    end;
  except
    //Any Error
    Raise;
  end;
end;

//Prepare progress
procedure TForm1.Table1BeforeScroll(DataSet: TDataSet);
begin
  screen.cursor := crhourglass;
  ProgressBar1.Position := 0;
end;

//some Progress
procedure TForm1.Image1Progress(Sender: TObject; Stage: TProgressStage;
  PercentDone: Byte; RedrawNow: Boolean; const R: TRect;
  const Msg: String);
begin
  Progressbar1.Position := Percentdone;
end;


//PreInit index
procedure TForm1.Table1AfterInsert(DataSet: TDataSet);
begin
  Table1.FieldByName('ID').AsFloat := -1;
end;

//Supply index, not a optimal method, but works in local enviroments
procedure TForm1.Table1BeforePost(DataSet: TDataSet);
begin
  If table1.State = dsInsert then
  begin
    table2.open;
    table2.last;
    Table1.FieldByName('ID').AsFloat := Table2.FieldByName('ID').AsFloat + 1;
    Table2.Close;
  end;
end;

//Save any Blobcontent to a file
procedure TForm1.Button2Click(Sender: TObject);
begin
  if (Table1.FieldByName('Picture').IsBlob) and
     (not(Table1.FieldByName('Picture').IsNull)) then
  begin
    SaveDialog1.Filter := '*.'+lowercase(Table1.FieldByName('Typ').AsString);
    SaveDialog1.Filter := SaveDialog1.Filter+'|'+SaveDialog1.Filter;
    SaveDialog1.DefaultExt := lowercase(Table1.FieldByName('Typ').AsString);
    if SaveDialog1.Execute then
    try
      TBlobField(Table1.FieldByName('Picture')).SaveToFile(SaveDialog1.FileName);
    except
      Raise;
    end;
  end
  else Showmessage('Nothing to Restore');
end;

end.


hope this helps

meikl ;-)
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Graphics Software

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.