![]() |
|
|
|
| ||||||
|
Welcome to the The ProgrammersTalk Community forums. You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content and access many other special features. Registration is fast, simple and absolutely free so please, join our community today! If you have any problems with the registration process or your account login, please contact contact us. |
![]() |
![]() | | LinkBack | Thread Tools | Display Modes | ![]() |
| |||
| To use this code, each image is loaded one at a time and inserted into a temporary holding file which is then saved all in one go. First we prepare the locals. Tempfile is used to store, read and save the final file temporarily. It's basically a holding space for the current state of play until the user decides to name and save the file officially. Transfer is the new file that is being built up. Newpic is for holding the picture we just loaded. We then load the image to be saved. Openimg in this case is an openimg dialog. tempfile := tfilestream.Create(tempfilename,fmopenreadwrite); transfer := tmemorystream.Create; newpic := tmemorystream.Create; currentimage.LoadFromFile(openimg.FileName); Having acquired the image to be saved, we record it temporarily into the currentimage stream, make a note of its size and reset the position of the read pointer to the beginning of the stream. 'Figure' is a record object that keeps track of how big each picture in the file is, amongst other things. I never worked out why you can't read the image straight into the new stream as you build it, but I couldn't get it to work that way! currentimage.SaveToStream(newpic); figure.bytesize[currentshot] := newpic.position; newpic.Position := 0; My picture files always had ten images, hence n = 1 to 10. You can adapt this for the number of pictures you use, or use a while loop and record how many pictures there are in your Figure record instead. My code relied on each picture being numbered from zero to ten though. This part of the code scans through each image. If the image is the current image, and hence the one being replaced, then it copies the new picture into place. For example if I'm replacing the 5th image in line, currentshot would be 5. If it's not the correct shot then the picture that is currently in the temporary file is transferred instead. for n := 1 to 10 do if n = currentshot then transfer.CopyFrom(newpic,newpic.Size) else if (figure.bytesize[n] > 0) then transfer.CopyFrom(tempfile,figure.bytesize[n]); Here we clean up the bits and pieces. The tempfile is freed and deleted, now that all of the important information is in Transfer. Transfer is then copied into the tempfile and saved. System resources are then freed from the unneeded pictures, streams and fileholders. Don't forget that the file position pointer changes with almost every file or stream action you perform. tempfile.free; deletefile(tempfilename); tempfile := tfilestream.Create(tempfilename,fmcreate); transfer.Position := 0; tempfile.CopyFrom(transfer,transfer.Size); tempfile.Free; transfer.Free; newpic.Free; Now when you read the file, all you have to do is parse through the Figure record, adding up the filesize of each picture (and the header itself) until you reach the picture you want. Then you use the CopyFrom command to read the next X bytes into your target image, using the filesize of that image as X. Hope this helps! Ash |
| The Following User Says Thank You to Destriarch For This Useful Post: | ||
HelloWorld (01-24-2008) | ||
| |||
| Yeah, a database would help in this but... The application im programming isnt anything professional but it is intented to run in a lot of different clients. For database i will need to install BDE into client machines and thus making the hole proccess more complicated and less reliable. So if there´s a way to use streams (i know there´s a way), i choose this method to achieve what i need because is the simpliest way, not just to be the simpliest but it also completely make possible what i need. I was looking in here: Streams, streams, ... TStream and tried to understand the proccess and apply to my case.... but i think i dont have enought skills to do.... I still apreciate any possible help on Destriarch TStream subject. Regards |
| The Following User Says Thank You to DanDare For This Useful Post: | ||
HelloWorld (01-24-2008) | ||
| |||
| Hhahaha, this was really unusual. The time between I opening the thread and making my last post was the time when Destriarch replied..... Thank you for the reply im going to read this now. Salute |
| |||
| Ok, I´ve spent the last 3 days (i know it sounds dumb) trying to achieve the goal of writting and loading jpeg images from stream as permit me to store all the jpeg´s into a unique solid archive and finally got the conceptual idea working. I did this way: ====================== CODE =========================== var apeg: TJpegImage ; apeg2: TJpegImage ; stream: TStream ; stream2: TStream ; stream3: TStream ; ASize: LongInt ; ASize2: LongInt ; begin stream := TMemoryStream.create ; stream2 := TMemoryStream.create ; stream3 := TMemoryStream.create ; apeg := TJpegImage.create ; apeg2 := TJpegImage.create ; apeg.LoadFromFile('f1.jpg'); apeg.SaveToStream(stream); ASize := stream.Size ; stream2.write(ASize, Sizeof(ASize)) ; stream.position := 0 ; stream2.CopyFrom(stream, ASize) ; stream2.Position := 0 ; stream2.read(ASize, Sizeof(ASize)) ; stream3.copyfrom(stream2, ASize) ; showmessage(inttostr(stream3.size)) ; stream3.position := 0 ; apeg2.LoadFromStream(stream3); stream3.free ; stream2.free ; stream.Free ; image1.Picture.assign(apeg2) ; end ; ==================== CODE ================================ I guess now that its just a matter of keep track of each jpeg position (or total size in bytes until the desired image) in the stream and save or load the stream to a file. Thank you guys for this thread toughts. Salute Last edited by DanDare : 01-26-2008 at 06:37 PM. |
| |||
| My last post contains errors (or at least not usable logic). This is the workable way i found to do the thing: var i: integer ; apeg: TJpegimage ; apeg2: TJpegimage ; stream: Tstream ; stream2: Tstream ; stream3: Tstream ; ASize: LongInt ; begin apeg := TJpegImage.create ; apeg2 := TJpegImage.create ; stream := TMemorystream.create ; stream2 := TMemoryStream.create ; for i := 1 to 10 do // load 10 images in this example begin cout [i] := stream2.position ; // stores stream position of each image for future use in an LongInt array type apeg.LoadFromFile('f' + (inttostr(i)) + '.jpg'); // load the numbered sequence of images apeg.SaveToStream(stream); ASize := stream.Size ; stream2.write(ASize, Sizeof(ASize)) ; stream.position := 0 ; stream2.CopyFrom(stream, ASize) ; stream.Free ; // Free this stream for the next round stream := TMemoryStream.create ; end; // Load Sequence stream2.position := 0 ; stream2.Seek(cout[5], sofrombeginning) ; // In this example we will load the image N. 5 stream3 := Tmemorystream.Create ; stream2.read(ASize, Sizeof(ASize)) ; stream3.copyfrom(stream2, ASize) ; stream3.position := 0 ; apeg2.LoadFromStream(stream3); stream3.free ; stream2.Free ; stream.Free ; image1.Picture.assign(apeg2) ; for i := 1 to 10 do begin memo1.Lines.Add (inttostr(cout[i])); // this show you the Int values created for the indexing end; // ================ CODE ================================ P.S. I will use such type of code to load predefined jpeg´s that an application uses (usage). Salute Last edited by DanDare : 01-26-2008 at 10:29 PM. |
![]() |
| Thread Tools | |
| Display Modes | |
| |