PNGCRUSH a Directory of Images
Written by David Walsh on September 24, 2009 · 17 Comments
One easy way of reducing website load time is by optimizing your images. PNG graphics are often more bloated than they need to be so using PNGCRUSH should be a no-brainer. PNGCRUSH's basic usage provides only single-file-crushage but I've created a script that crushes PNGs in directories recursively.
The Bash Script
#!/bin/sh for png in `find $1 -name "*.png"`; do echo "crushing $png" pngcrush -brute "$png" temp.png mv -f temp.png $png done;
Do whatever you can to compress your images so that your website will load as quickly as possible. PNGCRUSHing your images does not cause a loss of quality -- only a loss of excess file size! PNGCRUSHing my images saved over 120KB of bloated imagery for the recent redesign.
heh, this post is so engrish: “so that your website load as quickly” and “does not cause a lose of quality”. mootools crew must be whipping you hard then :)
pngcrush… was this something you found on your mac thingie? most inconsiderate of “normal” windows users :D
Holy crap. In my defense this was a really late night post. Weak. My bad.
Totally untested, but for windows users, as long as everything is in the one spot….
Create a batch file called “crush.bat”
Put the following code in it.
@echo off
for /f “tokens=*” %%x in (‘dir /b *.png’) do (
echo “crushing %%x”
pngcrush -brute “%%x” temp.png
move /Y temp.png “%%x”
)
Then run it.
Is there a way to do this with PHP? Or something a bit more practical?
@Ben: What’s impractical about this?
@David Walsh: I don’t know how to run bash scripts :)
Oh — in that case, try this:
http://pornel.net/imageoptim/en
Extended:
scriptname [-d directoryname]
[code]
#!/bin/sh
#
dflag=
while getopts 'd:' OPTION
do
case $OPTION in
d) dflag=$OPTARG
;;
?) printf "Usage: %s: [-d directory]\n" $(basename $0) >&2
exit 2
;;
esac
done
shift $(($OPTIND - 1))
if [ "$dflag" ]
then
# DO DIR PNGCRUSH
for png in `find $dflag -name "*.png"`;
do
echo "crushing $png"
pngcrush -brute "$png" temp.png
mv -f temp.png $png
done;
fi
[/code]
It’s even easier than that, pngcrush supports * for selecting images to crush. Try: ‘pngcrush -d “/Users/rd/crushedimages/” *.png’ to crush ALL png images in the current directory and put the resulting files in “/Users/rd/crushedimages/” (change this to a directory of your choosing!
i think this was a great post. it has helped me much. thank you
Very useful script!
In terms of usability and performance, under windoes, it doesn’t get better than this for a gui – http://pnggauntlet.com
a great feature is that you can simply drag/ drop images, and it will ‘smash’ them,a nd overwrite the original files on the fly.
for example, pull your entire website to a local folder, search for *.png in win explorer, then simply drag/ drop the query results into pnggauntlet, making sure to check the ‘overwrite original files’ box, and let it smash down the file size.
i just tested this workflow on a massive ecommerce website (about 2700 png’s worth about 40mb) and saved a whopping 3mb. of course, who knows how well the originals were optimized, but nonetheless, it’s a great result.
another great feature is that it can optionally convert from jpg, tiff, gif and bmp to png.
I was searching for some information on jpgcrush and google assumed I meant pngcrush… Anyway for anyone who is interested I have several tutorials on this subject (in python) one of which will make use of multiple processors (which saves quite a bit of time if you have a tonne of pngs.)
http://www.ragingsloth.com/softwareEng/PNGOptimizerIndex.html
Simplest way to do this.
1. Create a folder for executables which will go into your PATH directory reference.
2. Open folder containing PNGs you want to crush
3. shift + right click in empty space in folder, “open command window in folder”
4. type “pngcrush -d “crushed” *.png
5. close command window and go to newly created ‘crushed’ folder, which now contains your optimised PNGs.
Simplest way to do this.
1. Make sure that pngcrush.exe is in a folder which is mentioned in the PATH directory reference, so it can be used from the command line.
2. Open folder containing PNGs you want to crush.
3. shift + right click in empty space in folder, “open command window in folder”
4. type “pngcrush -d “crushed” *.png
5. close command window and go to newly created ‘crushed’ folder, which now contains your optimised PNGs.
How to get it to abort if file size will be INCREASED?!
| pngcrush 1.7.9
| Copyright (C) 1998-2002,2006-2010 Glenn Randers-Pehrson
| Copyright (C) 2005 Greg Roelofs
| This is a free, open-source program. Permission is irrevocably
| granted to everyone to use this version of pngcrush without
| payment of any fee.
| Executable name is pngcrush
| It was built with libpng version 1.2.42, and is
| running with libpng version 1.2.46 - July 9, 2011
| Copyright (C) 1998-2004,2006-2010 Glenn Randers-Pehrson,
| Copyright (C) 1996, 1997 Andreas Dilger,
| Copyright (C) 1995, Guy Eric Schalnat, Group 42 Inc.,
| and zlib version 1.2.3.3, Copyright (C) 1998-2002 (or later),
| Jean-loup Gailly and Mark Adler.
|| Warning: versions are different between png.h and png.c
|| png.h version: 1.2.42
|| png.c version: 1.2.46
| It was compiled with gcc version 4.4.4 and gas version 2.9.5(?).
Recompressing wut.png
Total length of data found in IDAT chunks = 548746
color counting (-cc option) is not supported.
Removed the pHYs chunk.
unknown chunk handling done.
IDAT length with method 11 (fm 0 zl 2 zs 2) = 2435942
IDAT length with method 12 (fm 1 zl 2 zs 2) = 951323
IDAT length with method 13 (fm 2 zl 2 zs 2) = 905037
IDAT length with method 14 (fm 3 zl 2 zs 2) = 1016476
IDAT length with method 15 (fm 4 zl 2 zs 2) = 858259
IDAT length with method 16 (fm 5 zl 2 zs 2) = 846721
IDAT length with method 17 (fm 0 zl 1 zs 0) = 697832
IDAT length with method 18 (fm 1 zl 1 zs 0) = 797697
IDAT length with method 19 (fm 2 zl 1 zs 0) = 755660
IDAT length with method 20 (fm 3 zl 1 zs 0) = 859270
IDAT length with method 21 (fm 4 zl 1 zs 0) = 761716
IDAT length with method 22 (fm 5 zl 1 zs 0) = 753877
IDAT length with method 23 (fm 0 zl 1 zs 1) = 697832
IDAT length with method 24 (fm 1 zl 1 zs 1) = 797697
IDAT length with method 25 (fm 2 zl 1 zs 1) = 755660
IDAT length with method 26 (fm 3 zl 1 zs 1) = 859270
IDAT length with method 27 (fm 4 zl 1 zs 1) = 761716
IDAT length with method 28 (fm 5 zl 1 zs 1) = 753877
IDAT length with method 29 (fm 0 zl 2 zs 0) = 673435
IDAT length with method 30 (fm 1 zl 2 zs 0) = 765510
IDAT length with method 31 (fm 2 zl 2 zs 0) = 731611
IDAT length with method 32 (fm 3 zl 2 zs 0) = 835291
IDAT length with method 33 (fm 4 zl 2 zs 0) = 735487
IDAT length with method 34 (fm 5 zl 2 zs 0) = 729097
IDAT length with method 35 (fm 0 zl 2 zs 1) = 673435
IDAT length with method 36 (fm 1 zl 2 zs 1) = 765510
IDAT length with method 37 (fm 2 zl 2 zs 1) = 731611
IDAT length with method 38 (fm 3 zl 2 zs 1) = 835291
IDAT length with method 39 (fm 4 zl 2 zs 1) = 735487
IDAT length with method 40 (fm 5 zl 2 zs 1) = 729097
IDAT length with method 41 (fm 0 zl 3 zs 0) = 654550
IDAT length with method 42 (fm 1 zl 3 zs 0) = 710763
IDAT length with method 43 (fm 2 zl 3 zs 0) = 694884
IDAT length with method 44 (fm 3 zl 3 zs 0) = 791240
IDAT length with method 45 (fm 4 zl 3 zs 0) = 694167
IDAT length with method 46 (fm 5 zl 3 zs 0) = 692165
IDAT length with method 47 (fm 0 zl 3 zs 1) = 654550
IDAT length with method 48 (fm 1 zl 3 zs 1) = 710763
IDAT length with method 49 (fm 2 zl 3 zs 1) = 694884
IDAT length with method 50 (fm 3 zl 3 zs 1) = 791240
IDAT length with method 51 (fm 4 zl 3 zs 1) = 694167
IDAT length with method 52 (fm 5 zl 3 zs 1) = 692165
IDAT length with method 53 (fm 0 zl 4 zs 0) = 587966
IDAT length with method 54 (fm 1 zl 4 zs 0) = 695367
IDAT length with method 55 (fm 2 zl 4 zs 0) = 672502
IDAT length with method 56 (fm 3 zl 4 zs 0) = 771732
IDAT length with method 57 (fm 4 zl 4 zs 0) = 675596
IDAT length with method 58 (fm 5 zl 4 zs 0) = 670186
IDAT length with method 59 (fm 0 zl 4 zs 1) = 634611
IDAT length with method 60 (fm 1 zl 4 zs 1) = 698306
IDAT length with method 61 (fm 2 zl 4 zs 1) = 688376
IDAT length with method 62 (fm 3 zl 4 zs 1) = 785595
IDAT length with method 63 (fm 4 zl 4 zs 1) = 680116
IDAT length with method 64 (fm 5 zl 4 zs 1) = 674963
IDAT length with method 65 (fm 0 zl 5 zs 0) = 567961
IDAT length with method 66 (fm 1 zl 5 zs 0) = 659745
IDAT length with method 67 (fm 2 zl 5 zs 0) = 651320
IDAT length with method 68 (fm 3 zl 5 zs 0) = 745437
IDAT length with method 69 (fm 4 zl 5 zs 0) = 648498
IDAT length with method 70 (fm 5 zl 5 zs 0) = 645942
IDAT length with method 71 (fm 0 zl 5 zs 1) = 615134
IDAT length with method 72 (fm 1 zl 5 zs 1) = 667126
IDAT length with method 73 (fm 2 zl 5 zs 1) = 669886
IDAT length with method 74 (fm 3 zl 5 zs 1) = 762645
IDAT length with method 75 (fm 4 zl 5 zs 1) = 658031
IDAT length with method 76 (fm 5 zl 5 zs 1) = 655619
IDAT length with method 77 (fm 0 zl 6 zs 0) = 560413
IDAT length with method 78 (fm 1 zl 6 zs 0) = 618874
IDAT length with method 79 (fm 2 zl 6 zs 0) = 623842
IDAT length with method 80 (fm 3 zl 6 zs 0) = 710951
IDAT length with method 81 (fm 4 zl 6 zs 0) = 618249
IDAT length with method 82 (fm 5 zl 6 zs 0) = 619695
IDAT length with method 83 (fm 0 zl 6 zs 1) = 606769
IDAT length with method 84 (fm 1 zl 6 zs 1) = 627807
IDAT length with method 85 (fm 2 zl 6 zs 1) = 643727
IDAT length with method 86 (fm 3 zl 6 zs 1) = 730353
IDAT length with method 87 (fm 4 zl 6 zs 1) = 629654
IDAT length with method 88 (fm 5 zl 6 zs 1) = 630925
IDAT length with method 89 (fm 0 zl 7 zs 0) = 558547
IDAT length with method 90 (fm 1 zl 7 zs 0) = 605505
IDAT length with method 91 (fm 2 zl 7 zs 0) = 612292
IDAT length with method 92 (fm 3 zl 7 zs 0) = 695889
IDAT length with method 93 (fm 4 zl 7 zs 0) = 608946
IDAT length with method 94 (fm 5 zl 7 zs 0) = 610519
IDAT length with method 95 (fm 0 zl 7 zs 1) = 604538
IDAT length with method 96 (fm 1 zl 7 zs 1) = 614662
IDAT length with method 97 (fm 2 zl 7 zs 1) = 631610
IDAT length with method 98 (fm 3 zl 7 zs 1) = 714922
IDAT length with method 99 (fm 4 zl 7 zs 1) = 620061
IDAT length with method 100 (fm 5 zl 7 zs 1) = 621519
IDAT length with method 101 (fm 0 zl 8 zs 0) = 555261
IDAT length with method 102 (fm 1 zl 8 zs 0) = 589149
IDAT length with method 103 (fm 2 zl 8 zs 0) = 597092
IDAT length with method 104 (fm 3 zl 8 zs 0) = 676219
IDAT length with method 105 (fm 4 zl 8 zs 0) = 596852
IDAT length with method 106 (fm 5 zl 8 zs 0) = 598205
IDAT length with method 107 (fm 0 zl 8 zs 1) = 600862
IDAT length with method 108 (fm 1 zl 8 zs 1) = 597438
IDAT length with method 109 (fm 2 zl 8 zs 1) = 614670
IDAT length with method 110 (fm 3 zl 8 zs 1) = 693766
IDAT length with method 111 (fm 4 zl 8 zs 1) = 606835
IDAT length with method 112 (fm 5 zl 8 zs 1) = 607756
IDAT length with method 113 (fm 0 zl 9 zs 0) = 554346
IDAT length with method 114 (fm 1 zl 9 zs 0) = 578629
IDAT length with method 115 (fm 2 zl 9 zs 0) = 587438
IDAT length with method 116 (fm 3 zl 9 zs 0) = 665646
IDAT length with method 117 (fm 4 zl 9 zs 0) = 586698
IDAT length with method 118 (fm 5 zl 9 zs 0) = 588334
IDAT length with method 119 (fm 0 zl 9 zs 1) = 599719
IDAT length with method 120 (fm 1 zl 9 zs 1) = 586780
IDAT length with method 121 (fm 2 zl 9 zs 1) = 603901
IDAT length with method 122 (fm 3 zl 9 zs 1) = 683089
IDAT length with method 123 (fm 4 zl 9 zs 1) = 595879
IDAT length with method 124 (fm 5 zl 9 zs 1) = 597310
IDAT length with method 125 (fm 0 zl 1 zs 3) = 2246417
IDAT length with method 126 (fm 1 zl 1 zs 3) = 876458
IDAT length with method 127 (fm 2 zl 1 zs 3) = 801576
IDAT length with method 128 (fm 3 zl 1 zs 3) = 940918
IDAT length with method 129 (fm 4 zl 1 zs 3) = 753268
IDAT length with method 130 (fm 5 zl 1 zs 3) = 741504
IDAT length with method 131 (fm 0 zl 4 zs 3) = 2245807
IDAT length with method 132 (fm 1 zl 4 zs 3) = 876189
IDAT length with method 133 (fm 2 zl 4 zs 3) = 801449
IDAT length with method 134 (fm 3 zl 4 zs 3) = 940635
IDAT length with method 135 (fm 4 zl 4 zs 3) = 753015
IDAT length with method 136 (fm 5 zl 4 zs 3) = 741282
Best pngcrush method = 113 (fm 0 zl 9 zs 0) for temp.png
(1.02% IDAT increase)
(1.02% filesize increase)
CPU time used = 47.830 seconds (decoding 2.470,
encoding 45.050, other 0.310 seconds)
4 months and no-one’s answered me… This problem really annoys me. It seems that pngcrush’s missing some packing methods…