[dbExpress][TMemoeryStream]Jak zapisać/odczytać JPG do bazy?

0

Chce obrazek jpg zapisać do bazy MySQL za pomocą dbExpress i potem go odczytać.
Obrazek w bazie chce zapisać jako LONGBLOB.
I robię coś takiego:

var
  buffer: array[0..1000000] of char;
  buf: string;
  i: integer;
  stream: TMemoryStream;
  jpg: TJPEGImage;
begin

  [...]

  stream := TMemoryStream.Create;
  jpg.SaveToStream(stream);
 
  stream.Read(buffer, stream.Size);
  for i:=0 to stream.Size-1 do buf := buf+buffer[i];

  with Baza do
  begin
    [...]
    Zapytanie.ParamByName('obrazek').AsBlob := buf;
    [...]
  end;

  stream.Free;
end;

W zmiennej buffer jest już niepoprawna zawartość bo gdy zapisuję ją do pliku to obrazek jest niepoprawny. Ale jeśli zrobię stream.SaveToFile(...) to obrazek wygląda prawidłowo.

A odczytuję z bazy tak:

var
  buf: array[0..1000000] of char;
  buffer: string;
  jpg: TJPEGImage;
  stream: TMemoryStream;
  wielkosc: Integer;
begin
  with Baza.ZapytanieSELECT do
  begin
    Open;
    stream := TMemoryStream.Create;

    while not Eof do
    begin
      wielkosc := FieldValues['wielkosc']; // wielkość danych w polu BLOB
      buffer := FieldValues['obrazek'];
      StrPCopy(buf, buffer);
      stream.Write(buf, wielkosc);

      obrazek := TJPEGImage.Create;
      obrazek.LoadFromStream(stream);
      
      Next();
    end;
    stream.Free;
    Close();
  end;
  obrazek.SaveToFile('nazwa.jpg');
end;

No i oczywiście dane z pola BLOB są niepoprawne i obrazka nie ma :/

Błagam o pomoc bo siedzę na tym już parę godzin;)

Powiedzcie co robię źle.

0

ja robiłem to tak:

//--- ZAPIS ---

begin

//--- TU ROBISZ INSERTA ---

Data.CommandText := 'Select * from dbo.tbl_Definicje_Uzytkownikow where User_Id=100'; //Pobierasz ostatnio dodany rekord i edytujesz
Data.Open;
Data.Edit;
(Data.FieldByName('foto') as TBlobField).LoadFromFile(OpenDialog.FileName);
Data.Post;
Data.Close;
//--- ODCZYT ---

Var
MS     : TMemoryStream;
begin
Data.CommandText := 'Select * from dbo.tbl_Definicje_Uzytkownikow where User_Id=100';
Data.Open;
Data.First;
FotoUser.Picture.Graphic := Nil;

MS := TMemoryStream.Create();
(Data.FieldByName('foto')as TBlobField).SaveToStream(MS);
MS.SaveToFile('C:\foto.jpg');
MS.Free;
Data.Close;
FotoUser.Picture.LoadFromFile('C:\foto.jpg')
end;


Nie mam jak teraz tego sprawdzić ale z tego co pamietam to mi to działało z tym że ja zamiast dbExpress uzywalem ADO i zamiast MySQL uzywalem MSSQL ale powinno tez dzialac na mySQL a jesli nie to pewnie sobie poradzisz zeby cos z tym zrobic

0

No i działa ale zapisywanie do bazy zrobiłem trochę inaczej.

  
// Zapytanie: TSQLDataSet
// stream: TMemoryStream
Zapytanie.ParamByName('obrazek').LoadFromStream(stream, ftTypedBinary);
Zapytanie.ExecSQL();

A odczyt tak jak kolega wyżej proponował:

CommandText := 'SELECT * FROM zrzuty_ekranu ORDER BY data,godzina';
Open;
stream := TMemoryStream.Create;
stream.Clear;
while not Eof do
begin
  (FieldByName('obrazek') as TBlobField).SaveToStream(stream);
  stream.SaveToFile('obrazek.jpg');
  Image1.Picture.LoadFromFile('obrazek.jpg');
  Next();
end;
stream.Free;
Close();

Tylko jak zrobić to aby nie trzeba było zapisywać do pliku tylko od razu zapisać do TImage??

0

a przez LoadFromStream nie probowałeś?

0

Chodzi Ci aby zrobić coś takiego:

Image1.Picture.LoadFromStream(...)

?
Ale Picture nie ma takiej metody.

Próbowałem też tak:

jpg := TJPEGImage.Create;
jpg.LoadFromStream(stream);
Image.Picture.Assign(jpg);

Ale się nie udało :/

0

A po co w ogole zaśmiecać bazę obrazkami?
W bazie przechowujesz linki lub nazwy obrazków.

0

Dlatego, że mam dwa kompy bez stałego IP i nie mogą się bezpośrednio połączyć. Serwer bazy ma służyć jako pośrednik w przesyłaniu zrzutu ekranu z jednego kompa na drugi.

1 użytkowników online, w tym zalogowanych: 0, gości: 1