PngCrush can already handle multiple file names given to it on the command line. In this case all you'd have to do would be to pass %*
to PngCrush instead of just %1
(as you probably do now):
@pngcrush %*
%*
contains all arguments to the batch file, so this is a convenient way to pass all arguments to another program. Careful with files named like PngCrush options, though. UNIX geeks will know that problem :-)
After reading your post describing your technique, however, this won't work properly as you are writing the compressed file to new.png
. A bad idea if you're handling multiple files at once as there can be only one new.png
:-). But I just tried out that PngCrush handles multiple files just well, so if you don't mind an in-place update of the files then putting
@pngcrush -reduce -brute %*
into your batch will do the job (following your original article).
PngCrush will not handle multiple files or you want to write each image to a new file after compression. In this case you stick with your "one file at a time" routine but you loop over the input arguments. In this case, it's easiest to just build a little loop and shift
the arguments each time you process one:
@echo off
if [%1]==[] goto :eof
:loop
pngcrush -reduce -brute %1 "%~dpn1_new%~x1"
shift
if not [%1]==[] goto loop
What we're doing here is simple: First we skip the entire batch if it is run without arguments, then we define a label to jump to: loop
. Inside we simply run PngCrush on the first argument, giving the compressed file a new name. You may want to read up on the path dissection syntax I used here in help call
. Basically what I'm doing here is name the file exactly as before; I just stick "_new" to the end of the file name (before the extension). %~dpn1
expands to drive, path and file name (without extension), while %~x1
expands to the extension, including the dot.
ETA: Eep, I just read your desired output with new.png, new(1).png, etc. In this case we don't need any fancy path dissections but we have other problems to care about.
The easiest way would probably be to just start a counter at 0 before we process the first file and increment it each time we process another one:
@echo off
if [%1]==[] goto :eof
set n=0
:loop
if %n%==0 (
pngcrush -reduce -brute %1 new.png
) else (
pngcrush -reduce -brute %1 new^(%n%^).png
)
shift
set /a n+=1
if not [%1]==[] goto loop
%n%
is our counter here and we handle the case where n
is 0 by writing the result to new.png
, instead of new(0).png
.
This approach has problems, though. If there are already files named new.png
or new(x).png
then you will probably clobber them. Not nice. So we have to do something different and check whether we can actually use the file names:
rem check for new.png
if exist new.png (set n=1) else (set n=0 & goto loop)
rem check for numbered new(x).png
:checkloop
if not exist new^(%n%^).png goto loop
set /a n+=1
goto checkloop
The rest of the program stays the same, including the normal loop. But now we start at the first unused file name and avoid overwriting files that are already there.