Thursday, April 14, 2011

How to add increasing number to saved files in Delphi?

I'm making a program that takes a snapshot of the screen, and saves it to a folder as a Bitmap picture. I seem to be running into a problem though, the picture just overwrites itself.

Can anyone tell me how I can make it so when it saves, the number will be one higher than the last? For example: Save 1: Screenshot0001.bmp Save 2: Screenshot0002.bmp Save 3: Screenshot0003.bmp

And so on.

From stackoverflow
  • At program startup, iterate all Screenshot*.bmp files, parse out the numeric part and find the highest - assign this value to your counter. When doing a snapshot, go into a loop that tries crreating Screenshot.bmp with "only create if doesn't exist already" (CREATE_NEW) semantics, incrementing the counter until you find an unused name.

    Alternately, use timestamp instead of counter :)

    mghie : +1 for the tip to do this atomically (multi-user friendly). But given the experience level of the OP the other answer seems to be more appropriate.
  • There are many ways to accomplish something like this.

    1. Do it like your digital camera does; Have a counter and save it in a file or in the registry. You'll probably run into multi-user problems and you'll still have to handle situations where an image already exists.

    2. Don't use a incrementing number, but write a datetime in the filename. FileName := 'Screenshot_'+FormatDateTime('yyyymmdd-hhnnss-zzz.bmp',now());

    3. Do something like the code below to find the latest number. I think this does what you're describing, but remember that this code will get slower as you write more images. With thousands of pictures and a slow drive or network it could 'hang' your program.

    ..

    i := 0;
    while FileExists(Format('%sScreenshot%.04d.bmp',[ImgPath,i])) do
      inc(i);
    
    PuppyKevin : I'm having a problem. I added FileName := +FormatDateTime('yyyymmdd-hhnnss-zzz.bmp',now()); and added [FileName] to the following code: bmp.SaveToFile('C:\Screenshots\ScreenShot[FileName].bmp'); But I don't know if I am doing it right. The FileName:= says that it is undeclared.
    Rob Kennedy : You need to declare your variables, Kevin. Check the help about that. Also check the help about string concatenation.
    PuppyKevin : I declared the FileName variable as FileName: string;, I re-wrote the FileName := and SaveTo lines as: FileName := 'Screenshot_'+FormatDateTime('yyyymmdd-hhnnss-zzz',now()); bmp.SaveToFile('C:\Screenshots\[FileName].bmp');, and now, when it makes and saves the Bitmap, it comes out as [FileName].bmp.
    mghie : @PuppyKevin: Try "bmp.SaveToFile('C:\Screenshots\' + FileName + '.bmp');" instead, or use another Format() call: "bmp.SaveToFile(Format('C:\Screenshots\%s.bmp', [FileName]));"
    PuppyKevin : mghie, I used your Format() way, and it worked! Thank you everyone for helping me out :)
  • You need a routine like this which mimics Windows file duplication where the first file is 'My File', the second is 'My File (2)', then 'My File (3)' etc.

    function AppendDuplicationNumber( const AStr : string ) : string;
    // Used to make strings unique
    // This examines the string AStr for trailing '(n)' where
    // 'n' is an integer.
    // If the (n) part is found, n is incremented, otherwise '(2)' is
    // appended to the string.
    var
      iLH, iRH, I : integer;
      S           : string;
    begin
      Result := AStr;
      iLH    := CharPosBackwards( '(', Result );
      If iLH > 0 then
        begin
        iRH := PosEx( ')', Result, iLH );
        If iRH > 0 then
          begin
          I := StrToIntDef( Copy( Result, iLH+1, iRH-iLH-1 ), 0 );
          If I > 0 then
            begin
            Inc(I);
            S := IntToStr( I );
            Delete( Result, iLH+1, iRH-iLH-1 );
            Insert( S, Result, iLH+1 );
            Exit;
            end;
          end;
        end;
    
      // Did not increment existing (n), so append it.
      Result := Result + ' (2)';
    end;
    
    mghie : This is clearly not what the OP intended, he specifically wants file names with one part being an increasing number.

0 comments:

Post a Comment