Skip to content

Commit

Permalink
Finish the CLI module. Release as 1.0.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
yumeyao committed Nov 13, 2013
1 parent 39454ef commit 76a9b25
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 26 deletions.
27 changes: 10 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#PNGOptim
PNGOptim is a CMD Batch file([Why]()?) for optimizing PNG files, aiming at good quality(small size) with less effort.
PNGOptim is a CMD Batch file([Why?](https://github.com/yumeyao/pngoptim/wiki/Why-using-CMD-Batch%3F)) for optimizing PNG files, aiming at good quality(small file size) with less effort(less tries hence runs faster).

It's inspired by similar projects such as [ImageOptim](http://imageoptim.com), [Trimage](http://trimage.org/), etc..
However, PNGOptim only uses [PNGOut](http://advsys.net/ken/utils.htm) and [Zopflipng](https://code.google.com/p/zopfli/)([Why](https://github.com/yumeyao/pngoptim/wiki/How-is-an-image-compressed-into-a-png%3F-How-to-choose-among-the-available-programs%3F)?), and is generally faster because it's SMART not BRUTE.
It's **inspired** by similar projects such as [ImageOptim](http://imageoptim.com), [Trimage](http://trimage.org/), etc..
However, PNGOptim doesn't follow all other projects' brute way, instead it only uses [PNGOut](http://advsys.net/ken/utils.htm) and [Zopflipng](https://code.google.com/p/zopfli/)([Why?](https://github.com/yumeyao/pngoptim/wiki/How-is-an-image-compressed-into-a-png%3F-How-to-choose-among-the-available-programs%3F)) in a smart way.

PNGOptim runs generally faster and the output is generally smaller because it's SMART not BRUTE.

###FEATURE
* Multi-CPU ready
Expand All @@ -12,11 +14,12 @@ However, PNGOptim only uses [PNGOut](http://advsys.net/ken/utils.htm) and [Zopfl

###Usage
1. Download the [batch file](https://raw.github.com/yumeyao/pngoptim/master/pngoptim.cmd)(you can right-click and choose save).
2. Ensure you have a copy of [PNGOut](http://advsys.net/ken/utils.htm), [Zopflipng](https://code.google.com/p/zopfli/) and [DeflOpt](http://www.walbeehm.com/download/) and they are accessable(you can just put the exe files to the same directory as the batch file)<br>
2. Ensure you have a copy of [PNGOut](http://advsys.net/ken/utils.htm), [Zopflipng](https://raw.github.com/yumeyao/pngoptim/master/zopflipng.exe) and [DeflOpt](http://www.walbeehm.com/download/) and they are accessable(you can just put the exe files to the same directory as the batch file)<br>
_As a respect of the authors, I DON'T contain the exe files in this project_
3. Now use it to optimize PNG files. They are optimized in-place.
* Drag'n'Drop PNGs to the batch file.
* Use the syntax "pngoptim pngfile1 pngfile2 pngfile3 pngfile4 ...".<br>
* Drag'n'Drop PNGs to the batch file or d'n'd folders.
* Use the syntax "pngoptim pngfile1 pngfile2 pngfile3 pngfile4 ...".
* Just run the command to see more syntax.

###Limit
1. On XP Home/2000, wmic is not present, assuming 2 logical CPUs.<br>
Expand All @@ -26,14 +29,4 @@ Search for "InitParallel 2" and replace 2 in case you want to change the numbers
However it's not recommended to run multiple instances and it's not needed, you doesn't benefit from doing so.

###TODO
1. The output is sometimes not optimal when the output is in patterned colorspace.<br>
This is because zopflipng don't change the color pattern <br>
It seems PNGOut uses a random pattern layout so it might make sense to do multiple tries in the first pass
2. Even if the output is not in patterned colorspace, the output is not smallest all the time(compared to brute).<br>
Because this script uses zopfli -q --filters=01234mepb as 1st pass to select best filter, and only use zopfli --filters=p in 2nd pass(that's why this script is faster).<br>
We should use --filters=xxxxx where xxxxx is all possible good filters.
3. Even we use --filters=01234mepb --iterations=500, there is a tiny chance the output is not smallest(compared to brute).<br>
See -r option of pngout. This is INSANE!<br>
4. allow for specifying --iterations for zopflipng.
5. switches
6. log and -v = verbose
1. log in verbose mode.
91 changes: 82 additions & 9 deletions pngoptim.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,103 @@ if defined pngout if defined zopflipng if defined deflopt goto:Main
endlocal & goto:eof

:Main
echo ************************************************************
echo pngoptim 1.0.0 - by yumeyao
echo ************************************************************
if a==%1a goto:Usage
set ParallelCmd=%0
call:InitSessionID pngoptim
echo Session ID: %sessionid%
echo Session ID: %sessionid%>%sessionid%.log
echo.>>%sessionid%.log
echo(>>%sessionid%.log
echo Log File: %__cd__%%sessionid%.log
echo(
call:InitParallel 2

set zopfliiterations=
set pngouttryouts=20
set pngcount=0
set recursive=

for /f "delims=" %%i in ('dir /b/s %1') do (
set /a pngcount=!pngcount!+1
call:StartProcess cmd /c %0 "func::compress" "%%i"
set filelist=
set argvn=%1
:CheckArgs
if "!argvn:~0,1!" neq "-" if "!argvn:~0,1!" neq "/" (
set filelist=!filelist! !argvn!
goto:CheckNextArg
)
if /i "!argvn:~1,1!" equ "s" (set recursive=s&goto:CheckNextArg)
if /i "!argvn:~1,1!" equ "r" (set recursive=r&goto:CheckNextArg)
set argvnparameter=!argvn:~2!
if /i "!argvn:~1,1!" equ "z" (
set /a zopfliiterations=argvnparameter+0
if !zopfliiterations! neq 0 (set zopfliiterations="--iterations=!zopfliiterations!") else set zopfliiterations=
goto:CheckNextArg
)
if /i "!argvn:~1,1!" equ "y" (
set /a pngouttryouts=argvnparameter+0
if !pngouttryouts! equ 0 set pngouttryouts=20
goto:CheckNextArg
)
:CheckNextArg
shift
set argvn=%1
if defined argvn goto:CheckArgs

call:WaitForAllProcess
set pngcount=0
if defined filelist call:ProcessFiles %filelist%

rd /q /s "%sessiontmpdir%" >nul 2>nul
::rd /q /s "%sessiontmpdir%" >nul 2>nul
endlocal & goto:eof

:ProcessFiles
if !recursive! equ r (set usedir=true) else (
set usedir=false
(echo %1 | findstr [?*] >nul 2>nul) && (if defined recursive set usedir=true)
)
if !usedir!==true (set forpart1=/f "delims=" &set "forpart2='2^>nul dir /b/s %1'")
if !usedir!==false (set forpart2=%1 &set forpart1=)

set fileattr=%~a1
if "!fileattr:~0,1!" equ "d" (
set forpart1=/f "delims="
set "forpart2='2^>nul dir /b/s %1\*.png'"
)

for %forpart1%%%i in (%forpart2%) do if exist %%i (
set /a pngcount=!pngcount!+1
call:StartProcess cmd /c %ParallelCmd% "func::compress" "%%i"
) else if !usedir==false! (
echo File %i doesn't exist.
echo File %i doesn't exist.>>%sessionid%.log
echo(
echo(>>%sessionid%.log
)

shift
if not a==a%1 goto:ProcessFiles

call:WaitForAllProcess
goto:eof

:Usage:
echo>&2 Usage: %0 pngfiles
echo>&2 Usage: %~n0 pngfiles [options ^| pngfiles]
echo>&2(
echo>&2 Options:
echo>&2 /z[num] Set --iterations=num for zopflipng (default not specified)
echo>&2 /y[num] Set how many times to try pngout (default = 20)
echo>&2 /s subdirs
echo>&2 /r recursive
echo>&2 %~n0 [/s^|/r] a.png b*.png
echo>&2 a.png b1.png subdir\a.png subdir\b1.png
echo>&2 /s Yes Yes Yes
echo>&2 /r Yes Yes Yes Yes
echo>&2(
echo>&2 Suggested Presets:
echo>&2 FAST without /z /y specified
echo>&2 NORMAL /z20 /y50
echo>&2 SLOW /z100 /y500
echo>&2 INSANE /z500 /y1500
echo>&2(
endlocal & goto:eof

:zopflipng_parse
Expand Down Expand Up @@ -160,7 +232,7 @@ if not defined p3t1size set choosewhich=2
if not defined p3t2size set choosewhich=1
if not defined choosewhich (
set choosewhich=2
if %p3t1size% lss %p3t2size% set choosewhich=1
if !p3t1size! lss !p3t2size! set choosewhich=1
)
ren "%sessiontmpdir%\p%pngcount%p3t%choosewhich%.png" p%pngcount%p3.png
del /q/f/a "%sessiontmpdir%\p%pngcount%p3t*.png" >nul 2>nul
Expand Down Expand Up @@ -203,6 +275,7 @@ if not %output%==0 (
set /a sizepercent=outputsize * 10000 / p0size
set /a sizepercentleft=!sizepercent! / 100
set /a sizepercentright=!sizepercent! %% 100
if !sizepercentright! lss 10 set sizepercentleft=0!sizepercentright!
echo Optimized: %p0size% -^> %outputsize%, size decreased to !sizepercentleft!.!sizepercentright!%%
copy "%sessiontmpdir%\p%pngcount%p%output%.png" %1 >nul 2>nul
) else (
Expand Down

0 comments on commit 76a9b25

Please sign in to comment.