Šta je novo?

DELPHI - Snimanje vise slika u FileStream

kefalo

Čuven
Učlanjen(a)
26.12.2002
Poruke
100
Poena
619
Potrebno je da se snime podaci u fajl na sljedeci nacin:
podaci1 (tipa integer)
slika1 (bitmapa ili jpeg)
podaci2
slika2
...
Uspio sam snimiti
podaci1
slika1
Podaci se lako iscitaju iz FileStreama, a sliku sam iscitavao sa
Image1.LoadFromStream(Stream);

// snimanje u FileStream podataka sa jednom slikom
procedure TForm1.Button3Click(Sender: TObject);
begin
Stream := TFileStream.Create('c:\test.dat', fmCreate);
with obrazac do
begin
Slika:=Tjpegimage.Create;
poljeX:=33;
poljeY:=66;
slika.LoadFromFile('c:\smor.jpg');
Stream.WriteBuffer(poljex, SizeOf(integer));
Stream.WriteBuffer(poljey, SizeOf(integer));
slika.SaveToStream(Stream);
Slika.Destroy;
end;
Stream.Free;
end;

//iscitavanje iz FileStreama
procedure TForm1.Button4Click(Sender: TObject);
begin
Stream := TFileStream.Create('c:\test.dat', fmOpenRead);
with obrazac do
begin
Slika:=Tjpegimage.Create;
Stream.ReadBuffer(poljex, SizeOf(integer));
Stream.ReadBuffer(poljey, SizeOf(integer));
slika.LoadFromStream(Stream);
image1.Picture.Assign(slika);
listbox1.Items.Add(inttostr(poljex));
listbox2.Items.Add(inttostr(poljey));
slika.Destroy;
end;
Stream.Free;
end;


Slican problem je da se rijesi zapisivanje vise slika u jedan fajl, a zatim da se iscitaju iste...
Znam da je potrebno zapisati velicinu slike prethodno u fajl a zatim sliku iscitavati iz fajla prema toj velicini...
Kako iscitati sliku iz TFileStreama bez koristenja slika.LoadFromStream(Stream); ?

Hvala!
 
zar niko nista ne zna o FileStream-u??? dodjavola nadao sam se da cu ovde sigurno da nadjem odgovor i rjesenje kako da ovo uradim....

p.s.
silverglider zar ti nemozes da mi pomognes? :(

p.p.s.
jako sam :boom: :cuss: ctp; :S :( :evil: jer nemam :idea:
 
Eh, sto volim kada me prozovu poimence pa moram da odgovorim :)

Mozda nisam najbolje razumeo u cemu je problem ovde. Za snimanje vise slika u jedan fajl imas vise resenja:

1. moze ovako sa TFileStream i headerom; definises header recimo kao record koji sadrzi dimenzije slike u pixelima i velicinu slike u bajtovima. Tako da kada ucitas sliku, proveris dimenzije i velicinu (obicna sizeof funkcija); popunis taj header record, snimis njega, pa snimis sliku. Kod citanja opet otvoris file stream, procitas onoliko bajtova koliko ti je velicina headera (sizeof(myheader)), procitas x, y i velicinu i onda znas koliko dalje bajtova da procitas i da je to sto si procitao, u stvari, slika. Ukoliko treba da "setas" od slike do slike, uvek imas funkcije position odnosno seek. Seek radi tako sto pomera cursor (fajla, ne na ekraju) za onoliko bajtova koliko mu kazes; i uvek se pomeras sa seek( sizeof(myheader) + myheader.picsize, soFromCurrent), tj. pomeras se uvek za jedan korak koji je velicina headera + procitana velicina slike. Posto unapred ne znas koliko imas slika u fajlu, svako otvaranje fajla mora da bude sekvencijalno i krene od pocetka. Posto moze da se desi da to potraje, uradis prilikom otvaranja fajla jedno indexiranje; tj formiras listu (ili openarray ili tcollection) koja sadrzi taj tvoj header i pocetak svake slike (int64) tj. broj bajtova od pocetka fajla do te slike. Tada imas u memoriji lepo listu slika i kada ti treba peta, ne moras opet da prodjes prvih 4, nego uradis seek i citas.
Samu sliku mozes da citas na vise nacina - ako volis da koristis samo gotove metode, mozes da koristis uz filestream i jedan memorystream i to tako da filestream sadrzi sve ovde slike i headere, a memorystream sadrzi samo jednu, tekucu sliku (uzimas je sa memorystream.copyfrom); onda tvoj bitmap ucita sliku iz tog memory streama i isprazni ga. Ako volis nizi nivo, imas funkciju read, koja cita u bafer - kreiras prvo buffer kao array of bytes i procitas odredje broj bajtova od pocetne tacke u taj buffer (sa tom Read metodom). Ono sta je u baferu je tvoja slika - typecast ili snimanje u nesto drugo pa ubacivanje u tbitmap -> tvoj izbor.
Upisivanje ide slicno - uvek ides sa seek na kraj filestreama i upisujes novo.

2. nacin je da ne koristis stream, nego samo file (bez tipa, implicitno nazvan file of byte). Ovo je vise staromodan iliti c-ovski nacin. Mozes da upisujes samo slike, bez ikakvih headera - jednostavno kopiras fajl (sliku) u bafer i strpas bafer u file. Gde zavrsava jedna slika, a pocinje druga saznaces po tome sto svaki je svaki fajl morao da zavrsi sa CTRL+Z kodom. Dakle, opet jedan prelaz da se formira u memoriji lista sa informacijama koliko slika u fajlu ima i od kojeg bajta pocinju, koliko je koja slika velika (u bajtovima), itd. Kada ucitas sliku u memoriju (kao niz bajtova), uvek mozes da uradis typecast ili da property objeka preusmeris na adresu tog bafera. Pogledas malo i winapi da vidis kako moze da ti pomogne sa handlovima i slicno.

3. nacin je koristeci xml fajl; tu mozes da korists clientdataset komponente za rad sa bazama, pa imas uobicajeni set columna u tabeli - width, height, size (u bajtovima), blob (binary large object). Imas jedan lep demo u primerima koji dolaze u svaki delphi (bese mybase ili tako nesto). Kada se koristi borlandov datapacket v2 format zapisa tabele u xml, desice se to da ce cela slika biti sacuvana u xmlu kao atribut BMP=''.
Tu koristis standardne tehnike rada sa bazama i, naravno, DBimage komponentu.

Eto, par hintova, pa sad vidi dalje sta ti je lakse. U krajnjem slucaju, mozes kompletnu TImage klasu da citas/pises u stream sa stream.writecomponent/readcomponent, ukoliko nisi vican baferima, pointerima, itd.
 
silveru najljepsa ti HVALA!!!!

p.s.
a ja sam konj ctp; sto se nisam sjetio seek... radio sam sa njim u turbo pascalu josh u srednjoj.... jaooooo

p.p.s.
ujutro cu ovo da probam pa cu da javim jel sve OK... a bash sam levat...
 
Isplaniraj samo prvo sve strukture podataka; ukoliko radis neki npr. image viewer, onda dobro razmisli o headeru (recordu koji sadrzi informacije o slici); u takav header mozes da stavis ne samo dimenzije u pixelima, nego i ime slike (filename), format slike (tako da mozes da spremas i bmp, jpg, gif, itd) i unapred znas sta otvaras. Takodje mozes da prilikom snimanja slike u fajl napravis i manji thumbnail slike pa snimis i njega. Ili podelis, pa u jedan fajl snimas headere i thumbnailove, a u drug fajl (isto ime, druga extenzija) snimas headere i originalne slike.
 
Nazad
Vrh Dno