Results 1 to 15 of 15

Thread: Hoe laat ik een Image (Blob) uit een database zien in een listview ?

  1. #1

    Hoe laat ik een Image (Blob) uit een database zien in een listview ?

    Ik heb een simpele database en wil dit laten zien in een listview. kom dacht ik een aardig eindje maar het loopt mis bij het halen van de data uit de database.

    met een aparte unit uDbJpgTypes definieer ik de records,
    Code:
    unit uDbJpgTypes;
    
    interface
    
    Uses
      System.Generics.Collections, Data.db;
    
      Type
       TDbJpgRecord = Record
       Id : Integer;
       kks : String;
       foto : TBlobField;
       End;

    in een datamodule haal ik de velden op uit de database,
    Code:
    procedure TDMDbJpg.DbJpgList(aList: TDbJpgRij);
    var item: TDbJpgRecord;
        Stream : TStream;
    begin
      if aList <> nil then
       begin
        aList.Clear;
        fdqDbJpgSelectAll.Open;
        try
         while not fdqDbJpgSelectAll.Eof do
         begin
          item.Id := fdqDbJpgSelectAll.FieldByName('Id').AsInteger;
          item.kks := fdqDbJpgSelectAll.FieldByName('kks').AsString;
          Stream.Position := 0;
          Stream := fdqDbJpgSelectAll.CreateBlobStream(fdqDbJpgSelectAll.FieldByName('foto'), bmRead);
          try
            Item.foto.LoadFromStream(Stream);
          finally
            Stream.Free;
          end;
          aList.Add(item);
          fdqDbJpgSelectAll.Next;
         end;
        finally
         fdqDbJpgSelectAll.Close;
        end;
       end;
    end;
    de foutmelding die ik krijg is
    Click image for larger version. 

Name:	Knipsel.JPG 
Views:	185 
Size:	21.0 KB 
ID:	7797

    Als ik de foutopsporing (F9) gebruik kom ik bij een probleem met de stream uit.

    heeft iemand een idee waar het spaak loopt?
    Groet Ronaldo

  2. #2
    Je doet een stream free, maar de stream kan nog gebruikt worden in de while. Ik zou de free ook niet in deze functie zetten, omdat deze niet hier wordt gecreate.

  3. #3
    Senior Member Wok's Avatar
    Join Date
    Dec 2002
    Location
    Alkmaar
    Posts
    2,085
    Hallo,

    {uit het hoofd, net wakker...}

    Stream := fdqDbJpgSelectAll.CreateBlobStream(fdqDbJpgSelectA ll.FieldByName('foto'), bmRead);

    Je Stream is als TStream gedeclareerd, en je wilt een Blobstream aanmaken.
    Volgens mij gaat dat nooit goed.

    gr.Peter
    10.4.2, Delphi2010, of Lazarus 2.2.0

  4. #4
    Quote Originally Posted by Wok View Post
    Hallo,

    {uit het hoofd, net wakker...}

    Stream := fdqDbJpgSelectAll.CreateBlobStream(fdqDbJpgSelectA ll.FieldByName('foto'), bmRead);

    Je Stream is als TStream gedeclareerd, en je wilt een Blobstream aanmaken.
    Volgens mij gaat dat nooit goed.

    gr.Peter
    had op verschillende sites mijn info gezocht, en daar zag ik dat ze een TStream gebruikte, als je bv een memorystream wil gebruiken pikt delphi dat niet. Wat zou ik dan moeten veranderen om het werkend te krijgen ?
    Last edited by Ronaldinho; 09-Sep-18 at 14:34.

  5. #5
    Quote Originally Posted by luigi View Post
    Je doet een stream free, maar de stream kan nog gebruikt worden in de while. Ik zou de free ook niet in deze functie zetten, omdat deze niet hier wordt gecreate.
    ehhhh waar zou ik hem dan moeten zetten, zoals ik al zei is dit een zelf inelkaargeknusteld/samengestelde code....

  6. #6
    Sorry heb me vergist op de vroege zondag ochtend. (Had nog geen espresso gedronken ) Ik dacht je stream uit een methode parameter was.

  7. #7
    Senior Member Wok's Avatar
    Join Date
    Dec 2002
    Location
    Alkmaar
    Posts
    2,085
    Code:
    Procedure TDMDbJpg.DbJpgList(aList: TDbJpgRij);
    var item: TDbJpgRecord;
      Stream :  TBlobStream;   // deze declaratie
    begin
    gr.Peter
    10.4.2, Delphi2010, of Lazarus 2.2.0

  8. #8
    Stream : TBlobStream;
    Deze had ik al geprobeerd, maar hij herkend deze niet, ook niet als ik Data.db aan de uses toevoeg (wat hij de unit Types wel lukte).

    vreemd toch ?

  9. #9
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,708
    @Peter (Wok): een TBlobStream is gewoon een afgeleide van TStream, dus zolang je geen bepaalde
    eigenschappen van TBlobStream aanroept, mag je een variabele gewoon als voorouder declareren.

    Eenzelfde zie je overal in de Delphi source bij TStrings als parameter van een method; hier wordt
    een parameter ook nooit gedeclareerd als TStringList oid, maar gewoon als de voorouder "TStrings".

    Waar het fout gaat is de regel:
    Code:
    Item.foto.LoadFromStream(Stream);
    Het object Item.Foto is nog niet aangemaakt in het record.
    TMemoryLeak.Create(Nil);

  10. #10
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Volgens mij zit hier je probleem.

    Delphi Code:
    1. Type
    2.    TDbJpgRecord = Record
    3.    Id : Integer;
    4.    kks : String;
    5.    foto : TBlofbield;  <---- niet gelijk met stream
    6.    End;
    Delphi is great. Lazarus is more powerfull

  11. #11
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,708
    Quote Originally Posted by jkuiper View Post
    Volgens mij zit hier je probleem.
    Neuh... de logica is vreemd, maar een TBlobField heeft een method genaamd "LoadFromStream",
    dus dat zou moeten kunnen.

    Moet uiteraard Foto wel bestaan natuurlijk, anders krijg je een AV (zoals getoond in de opening post).
    Ik zou sowieso geen gebruik maken van een record, maar er gewoon een object van maken die
    dan ook verantwoordelijk is voor de aanmaak en/of vrijgave van foto.

    Foto zou ik dan veranderen in een TStream (je wilt alleen data opslaan in je record/object, niet het hele
    database-veld spul eromheen) of misschien zelfs beter meteen een TJPEGImage.
    Als je TDbJpgRij dan ook nog eens een afgeleide maakt van TObjectList, dan kan deze vervolgens weer
    verantwoordelijk worden gemaakt voor het correct opruimen van de items.
    TMemoryLeak.Create(Nil);

  12. #12
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,708
    Uit de losse pols, dus niet getest (het compileert wel):
    Delphi Code:
    1. unit Unit1;
    2.  
    3. interface
    4.  
    5. uses
    6.   Classes, SysUtils, Contnrs, DB, JPEG;
    7.  
    8. type
    9.   TDbJpgRecord = class(TObject)
    10.   private
    11.     FId: Integer;
    12.     Fkks: string;
    13.     FFoto: TJPEGImage;
    14.   public
    15.     constructor Create;
    16.     destructor Destroy; override;
    17.  
    18.     procedure LoadFromDataSet(ADataSet: TDataSet);
    19.  
    20.     property Id: Integer read FId;
    21.     property kks: string read Fkks;
    22.     property Foto: TJPEGImage read FFoto;
    23.   end;
    24.  
    25.   TDbJpgRecords = class(TObjectList)
    26.   private
    27.     function GetItem(Index: Integer): TDbJpgRecord;
    28.   public
    29.     function Add(ARecord: TDbJpgRecord): Integer;
    30.     function LoadFromDataSet(ADataSet: TDataSet): Integer;
    31.  
    32.     property Items[Index: Integer]: TDbJpgRecord read GetItem;
    33.   end;
    34.  
    35. implementation
    36.  
    37. { TDbJpgRecord }
    38.  
    39. constructor TDbJpgRecord.Create;
    40. begin
    41.   inherited Create;
    42.   FFoto := TJPEGImage.Create;
    43. end;
    44.  
    45. destructor TDbJpgRecord.Destroy;
    46. begin
    47.   FFoto.Free;
    48.   inherited Destroy;
    49. end;
    50.  
    51. procedure TDbJpgRecord.LoadFromDataSet(ADataSet: TDataSet);
    52. var
    53.   Stream: TStream;
    54. begin
    55.   FId := ADataSet.FieldByName('Id').AsInteger;
    56.   Fkks := ADataSet.FieldByName('kks').AsString;
    57.   Stream := ADataSet.CreateBlobStream(ADataSet.FieldByName('foto'), bmRead);
    58.   try
    59.      FFoto.LoadFromStream(Stream);
    60.   finally
    61.     Stream.Free;
    62.   end;
    63. end;
    64.  
    65. { TDbJpgRecords }
    66.  
    67. function TDbJpgRecords.GetItem(Index: Integer): TDbJpgRecord;
    68. begin
    69.   Result := TDbJpgRecord(inherited GetItem(Index));
    70. end;
    71.  
    72. function TDbJpgRecords.Add(ARecord: TDbJpgRecord): Integer;
    73. begin
    74.   Result := Inherited Add(ARecord);
    75. end;
    76.  
    77. function TDbJpgRecords.LoadFromDataSet(ADataSet: TDataSet): Integer;
    78. var
    79.   R: TDbJpgRecord;
    80. begin
    81.   if Assigned(ADataSet) then
    82.   begin
    83.     Result := 0;
    84.     ADataSet.First;
    85.     while not ADataSet.Eof do
    86.     begin
    87.       R := TDbJpgRecord.Create;
    88.       try
    89.         R.LoadFromDataSet(ADataSet);
    90.         if Add(R) >= 0 then
    91.           Inc(Result);
    92.       except
    93.         FreeAndNil(R);
    94.       end;
    95.       ADataSet.Next;
    96.     end;
    97.   end
    98.   else
    99.     Result := -1;
    100. end;
    101.  
    102. end.
    Dit is "Klassieke" Delphi code, dus zou moeten werken op zelfs de eerste Delphi's, maar
    je kunt het ook eenvoudig omschrijven naar generics (of een TCollection) als je dat mooier
    of fijner vindt.
    TMemoryLeak.Create(Nil);

  13. #13
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Ik lees ineens dat het FM is. Daar heb ik al iets voor gemaakt voor listview. De basis is wel MyDAC van devart met MySQL, maar met een kleine aanpassing werkt het voor alles. Er wordt gebruik gemaakt van een bindinglist, die de objecten leest en deze vertaald naar een listview.
    Delphi Code:
    1. type TCompetitie = class
    2. private
    3.     fselectie: string;
    4.     fPokemons: array[0..5] of TBitmap;
    5.     ftotaal: integer;
    6.     fvriendcode: string;
    7.     fDeelnemerID: integer;
    8.     fteam: string;
    9.     fnaam: string;
    10.  
    11.     procedure SetSelectie(const Value: string);
    12.     function GetPokemon1: TBitmap;
    13.     function GetPokemon2: TBitmap;
    14.     function GetPokemon3: TBitmap;
    15.     function GetPokemon4: TBitmap;
    16.     function GetPokemon5: TBitmap;
    17.     function GetPokemon6: TBitmap;
    18.     procedure SetPokemon1(const Value: TBitmap);
    19.     procedure SetPokemon2(const Value: TBitmap);
    20.     procedure SetPokemon3(const Value: TBitmap);
    21.     procedure SetPokemon4(const Value: TBitmap);
    22.     procedure SetPokemon5(const Value: TBitmap);
    23.     procedure SetPokemon6(const Value: TBitmap);
    24. public
    25.   constructor create;
    26.   destructor  Destroy; override;
    27.  
    28.   property deelnemerID : integer read fDeelnemerID write FDeelnemerID;
    29.   property naam        : string  read fnaam write fnaam;
    30.   property totaal      : integer read ftotaal write ftotaal;
    31.   property team        : string  read fteam write fteam;
    32.   property vriendcode  : string  read fvriendcode write fvriendcode;
    33.   property selectie    : string  read fselectie write SetSelectie;
    34.  
    35.   property pokemon1    : TBitmap read GetPokemon1 write SetPokemon1;
    36.   property pokemon2    : TBitmap read GetPokemon2 write SetPokemon2;
    37.   property pokemon3    : TBitmap read GetPokemon3 write SetPokemon3;
    38.   property pokemon4    : TBitmap read GetPokemon4 write SetPokemon4;
    39.   property pokemon5    : TBitmap read GetPokemon5 write SetPokemon5;
    40.   property pokemon6    : TBitmap read GetPokemon6 write SetPokemon6;
    41. end;
    Delphi Code:
    1. procedure TDMModule.DBHaalImages(aCompetitie : TCompetitie);
    2. var MyQuery : TMyQuery;
    3.     BlobStream : TMemoryStream;
    4.     Index : smallint;
    5. begin
    6.   MyQuery := TMyQuery.Create(nil);
    7.   Index   := 0;
    8.   try
    9.     MyQuery.Connection := MyConnection1;
    10.     MyQuery.SQL.Text := format('SELECT * FROM pokemons WHERE nummer in (%s)',[aCompetitie.selectie]);
    11.     MyQuery.Active := true;
    12.     if MyQuery.RecordCount > 0 then
    13.     begin
    14.       while not MyQuery.eof do
    15.       begin
    16.         try
    17.           BlobStream := TMemoryStream.Create;
    18.           Myquery.GetBlob(Myquery.FieldByName('afbeelding')).SaveToStream(BlobStream);
    19.           BlobStream.Position := 0;
    20.           case index of
    21.             0 : aCompetitie.pokemon1.LoadFromStream(Blobstream);
    22.             1 : aCompetitie.pokemon2.LoadFromStream(Blobstream);
    23.             2 : aCompetitie.pokemon3.LoadFromStream(Blobstream);
    24.             3 : aCompetitie.pokemon4.LoadFromStream(Blobstream);
    25.             4 : aCompetitie.pokemon5.LoadFromStream(Blobstream);
    26.             5 : aCompetitie.pokemon6.LoadFromStream(Blobstream);
    27.           end;
    28.           Index := Index + 1 ;
    29.         finally
    30.           Blobstream.free
    31.         end;
    32.         MyQuery.Next;
    33.       end;
    34.     end;
    35.  
    36.   finally
    37.     MyQuery.Free;
    38.   end;
    39. end;
    Delphi is great. Lazarus is more powerfull

  14. #14
    Waar het fout gaat is de regel:
    Code:
    Item.foto.LoadFromStream(Stream);
    Het object Item.Foto is nog niet aangemaakt in het record.[/QUOTE]

    Ja hier gaat het inderdaad fout , als je delphi run (f9) dan krijg je de onderstaande resultaten als je een breakpoint geef op de bovenstaande regel.
    Ik zie dat hij de Id en de kks wel keurig laat zien maar het veld foto krijgt een rare code. Ook zie ik dat de stream 0 blijft.
    Click image for larger version. 

Name:	VirtualBox_DelphiWindows_15_09_2018_21_49_49.jpg 
Views:	178 
Size:	52.0 KB 
ID:	7801

    Name:  VirtualBox_DelphiWindows_15_09_2018_21_51_17.jpg
Views: 659
Size:  22.6 KB

    de overige 2 antwoorden moet ik nog even verder op puzzelen, mijn kennis gaat (momenteel) nog niet ver genoeg om dit direkt te implementeren in mijn code. Wel veel dank hiervoor.

  15. #15
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,708
    Quote Originally Posted by Ronaldinho View Post
    Ook zie ik dat de stream 0 blijft.
    Nee, daar staan twee ( ) haakjes, wat betekent dat het object is aangemaakt.
    Als dat niet zo zou zijn geweest, dan had daar gestaan:
    Code:
    Stream | nil
    TMemoryLeak.Create(Nil);

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •