[delphi] bytea image uit postgresql-db zuigen

Pagina: 1
Acties:
  • 145 views sinds 30-01-2008
  • Reageer

  • Hardcell
  • Registratie: November 2004
  • Laatst online: 03-02-2023
Hoi,

ik probeer vanuit delphi jpeg images in te laden uit een postgresql database. Ik heb deze opgeslagen in de database als bytea. (in php doe ik dit met imagecreatefromstring) Ik kan hier op internet weinig informatie over vinden. Ook wat nu precies het verschil is tussen een bytea en een blob-field is me nog niet geheel duidelijk (ivm de bob-functies die in delphi zitten), dit is niet hetzelfde toch?

Alvast bedankt voor reactie!

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Waarmee (welke componenten) verkrijg je toegang tot postgresql vanuit Delphi? Die moet je vast kunnen vertellen welke type het binnen Delphi zou worden.

We adore chaos because we like to restore order - M.C. Escher


  • Hardcell
  • Registratie: November 2004
  • Laatst online: 03-02-2023
Ik gebruik hiervoor de PostgresqlDAC componenten van MicroOlap. Deze zijn ongeveer gelijk aan de standaard bde-componenten. Ik denk ook niet dat hier meer informatie te vinden is. Ik ben meer op zoek naar een manier om van een string (die wat in de db staat) een jpeg image te bouwen.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Ok, dat is duidelijk. In welk formaat is die string?

We adore chaos because we like to restore order - M.C. Escher


  • Hardcell
  • Registratie: November 2004
  • Laatst online: 03-02-2023
volgens mij heet dat gewoon bytea toch?

op deze manier gaat het vanuit een webinterface de database in: (let op, php code!)

code:
1
2
3
4
5
$fh = fopen($tempname, "rb");
$contents = pg_escape_bytea(fread ($fh, filesize($tempname)));
fclose ($fh);

dbQuery($db_conn, "insert into \"Images\" values ('$id','$login','$contents','')");

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Ik zou aan MicroOlap vragen of ze daar ook functies voor gemaakt hebben, want dat bytea is wel erg Postgresql specifiek.

We adore chaos because we like to restore order - M.C. Escher


  • Hardcell
  • Registratie: November 2004
  • Laatst online: 03-02-2023
hmm, bij microolap hebben ze alleen verstand van blob velden.
ik moet dus op een of andere manier van een string een image (jpeg) bouwen in delphi.
volgens mij moet k hier sowieso eerst een delphi versie van de functie pg_unescape_bytea overheengooien.

pg_escape_bytea() escapes string for bytea datatype. It returns escaped string.

Note: When you SELECT bytea type, PostgreSQL returns octal byte value prefixed by \ (e.g. \032). Users are supposed to convert back to binary format by yourself.

..komt uit de php documentatie.

dus concrete vragen:
1. enige hulp bij het trugzetten van deze bytea string naar de originele content van de image
2. hoe deze string om te bouwen naar een TJpegImage in delphi

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Converteer de octs naar een byte, stop ze allemaal in een TMemoryStream en laad de stream in met TJpegImage.LoadFromStream.

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Als aanvulling op het bericht hierboven. Volgens de PostgreSQL site kunnen alle octets escape karakters bevatten. Die moet je dus wel even afvangen :( http://www.postgresql.org...tml#DATATYPE-BINARY-TABLE

Maar misschien is het handiger om blobs te gebruiken ipv bytea velden. Is ook wat makkelijker te porten naar andere databases als dat ooit nodig is

[ Voor 15% gewijzigd door Verwijderd op 06-01-2005 21:29 ]


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 17-05 20:32

alienfruit

the alien you never expected

Kan je niet dei postgres_escape_* functie direct aanroepen vanuit de dll, ik weet zo 1-2-3 wat je dan terug krijgt.

  • Hardcell
  • Registratie: November 2004
  • Laatst online: 03-02-2023
goed, alvast bedankt voor alle tips tot nu toe.

de tussenstand is dat ik inmiddels de volgende 3 functies heb:

1. de OctToInt (waar k ff een OctToByte van hebt gemaakt, vind de memorystream beter smaken)
code:
1
2
3
4
5
6
7
8
9
10
11
function TdmPhotos.OctToByte(Value: string): Byte;
var i: Integer;
    b: Byte;
begin
  b := 0;
  for i := 1 to Length(Value) do
  begin
    b := b * 8 + StrToInt(Copy(Value, i, 1));
  end;
  Result := b;
end;


2. de readOctet functie, die octets leest een omzet naar Bytes en met de escaped characters overweg kan:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function TdmPhotos.readOctet: Byte;
var c: Char;
    oct: string;
begin
  c := fImageString[fImagePos];
  if c = '\' then
  begin
    Result := Ord('\');
    Inc(fImagePos);
  end
  else if c = '''' then
  begin
    Result := Ord('''');
    Inc(fImagePos);
  end
  else
  begin
    oct := copy(fImageString, fImagePos, 3);
    Result := OctToByte(oct);
    fImagePos := fImagePos + 3
  end;
end;


3. de convert functie die van de string een memorystream moet maken
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function TdmPhotos.ConvertImageString(img: string): TMemoryStream;
var c: char;
    b: Byte;
begin
  fImageString := img;
  fImagePos := 0;
  Result := TMemoryStream.Create;
  while fImagePos < StrLen(PChar(img)) do
  begin
    c := fImageString[fImagePos];
    Inc(fImagePos);
    if c = '\' then
    begin
      b := readOctet;
      Result.Read(b, 1)
    end
  end
end;


edit:

ff voor de duidelijkheid, fImageString en fImagePos zijn private fields voor respectievelijk de inhoud van het veld in de database en de huidige positie in deze string.


Tot nu toe geeft dit JPEG error #42, premature end of input file.

Tips en opmerkingen nog steeds welkom, meer info volgt...

[ Voor 9% gewijzigd door Hardcell op 07-01-2005 15:26 ]


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Lastig te zien zo. Een goede debug sessie zou meer uitsluitsel kunnen geven.

We adore chaos because we like to restore order - M.C. Escher


  • Hardcell
  • Registratie: November 2004
  • Laatst online: 03-02-2023
Hmjah,

als Query.FieldByName('image_data').AsString een lege string geeft is het niet vreemd dat de rest ook nix doet! 8)7

weet iemand waarom delphi dit niet vreet?
als ik via een webinterface dezelfde query doe krijg ik wel gewoon de inhoud van het bytea veld te zien dus hij is niet leeg.

edit:

ik heb ze toegevoegd bij de fields (dubbelklikken op de query, in dat lijstje) en delphi ziet hem wel gewoon als een TStringField?!

[ Voor 22% gewijzigd door Hardcell op 07-01-2005 16:21 ]


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 08:31

Creepy

Tactical Espionage Splatterer

Staat er niet base64 encoded data in die string?

Zie hier : http://nl3.php.net/manual...imagecreatefromstring.php. Ja dus, De string is base64 encoded. Base64 decoder eroverheen en dat in een memory stream gooien. .loadFromStream gebruiken en gaan :)

(Nu wel dat bytea type nog omzetten naar een string. maar dat moet ook niet al te moeilijk zijn met chr() ).

Ik was ff iets te snel met het lezen van dat code voorbeeld.

Kan je niet dat veld rechtstreeks als een stream inlezen zoals je dat ook met een blob zou doen?

[ Voor 38% gewijzigd door Creepy op 07-01-2005 16:43 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Hardcell schreef op vrijdag 07 januari 2005 @ 16:17:
als Query.FieldByName('image_data').AsString een lege string geeft is het niet vreemd dat de rest ook nix doet! 8)7
Lijkt me een vraag voor MicroOlap.

We adore chaos because we like to restore order - M.C. Escher


  • Hardcell
  • Registratie: November 2004
  • Laatst online: 03-02-2023
Creepy schreef op vrijdag 07 januari 2005 @ 16:29:
Kan je niet dat veld rechtstreeks als een stream inlezen zoals je dat ook met een blob zou doen?
net geprobeerd de het veld in een TStringStream te krijgen met Query.GetFieldData() maar ook deze stringstream blijft leeg..

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 08:31

Creepy

Tactical Espionage Splatterer

Probeer het eens in een memory stream, het zou best kunnen zijn dat jou database laag dat bytetype helemaal niet behandelt als een string. Als die mem. stream ook leegblijft dan kan je het beste zoals LordLarry al zegt eens contact opnmeen met MicroOlap

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Hardcell
  • Registratie: November 2004
  • Laatst online: 03-02-2023
code:
1
2
tmp_str := TMemoryStream.Create;
Query.GetFieldData(FieldByName('image_data'), tmp_str);


Als ik hierna de size van dit ding opvraag zegtie 0,
Heb maar es ff een meeltje gestuurd naar microolap..

  • Hardcell
  • Registratie: November 2004
  • Laatst online: 03-02-2023
GEFIKST!!

ff de oplossing voor als hier meerdere mensen mee gaan stoeien.
gebruik GEEN software van microOlap, dit zuigt echt enorm!

in plaats daarvan download de odbvc-driver van de postgresql-site en let op dat je bij de settings van je connectie "bytea as lo" aanzet. vervolgens kun je de bytea-velden gewoon als blob's benaderen.
Pagina: 1