Page 1 of 1

pngnq script

Posted: 2010-11-04T00:30:10-07:00
by Xinerama
Hello all.

I found a script that helped me convert WMF files to PNGs by recursively going through a directory tree.
I am very pleased with the result. However, I find that some of the PNG files are still bigger than the original WMF files. So I found this great utility that will make the PNGs even smaller. It's PNGNQ.

So here is the script that I used initially. I commented out the "mogrify" part that worked successfully and I would like to add some other things to it, but am not sure about the syntax nor if it will work correctly.

Code: Select all

#!/bin/bash
IFS=$'\t\n'
EXTS=( png PNG)
for EXT in ${EXTS[@]};
do
	for f in `find . -name "*.$EXT" -type f`;
	do
		dir=`dirname $f`
		ff=`basename $f`
		echo "Working ..........................."
                #mogrify  -format png -quality 90 "$f"
		
              ## This is the new stuff that I would like to add.
              ## The pngnq program has an option for overwriting the original png file, but I have yet to successfully get it to work correctly. 
                pngnq -v -n 256 "$f" # I'm not sure if it should be *.png instead of "$f" here.
	done
done
I wish I knew more about scripting. There are a number of things that I would like to do in addition to Just converting the images via a script.
For instance after I convert the files, how can I then use "mv" to rename them. Actually I could just leave them with the -nq8 extension
The other thing I would like to do is delete the old png after they've been converted.

Thanks everyone.

Re: pngnq script

Posted: 2010-11-04T00:37:09-07:00
by anthony
Warning the "pngnq" program creates 8 bit pallette PNG. That is itself a lossy operation, though generally results in a much smaller image. Its a bit like making a GIF style image with multiple semi-transparency (if you are using transparency).


As for using "mv" what's the problem exactly. Doing the string manipulation needed to remove the unwanted part? There is a number of programs that can help. "mved" "mv_perl" and on many linux "mmove"
the "mv_perl" script is in my non-IM software export releases...
http://www.cit.griffith.edu.au/~anthony/software/

Re: pngnq script

Posted: 2010-11-04T01:55:46-07:00
by Xinerama
Thanks for the "mved" tip.

So how can I modify the script to get pngnq to recursively enter directories?

Re: pngnq script (Using "find|xargs" )

Posted: 2010-11-04T18:21:32-07:00
by anthony
Typical way is to use find with xargs.

find {directory} -type f -name '*.name' -print0 | xargs -0r pngnq {options}

find starts at the given directory and recurses. listing all files
-type f limits it to outputing just files
-name '*.png' limits to names containing the PNG suffix
The -print0 is a slightly different output that handles directories and files that has spaces, or even return characters in them in them. Basically a 'safety' (security wise) technique If not given filenames are just printed one per line which can also be very useful!

xargs takes the filename read from its stdin and appends them to the given command until some limit (line length, number of files per command extra) is reached. As such it can run multiple pngnq commands when lots of files are found. the -0 is to tell it that the find is using the safer -print0 method for listing filenames.

In short "find" finds the filenames recursivally, and "xargs" runs the given command on those filenames.

For a better introduction see this Wikipedia page on xargs
http://en.wikipedia.org/wiki/Xargs

Re: pngnq script

Posted: 2010-11-06T11:10:42-07:00
by Xinerama
Thanks for replying Anthony.
I actually figured it out with a huge one-liner using a bunch of ";" and "&&". Hahhaaha
I DO really appreciate you coming back and checking on this thread.
Sooooo, I guess the only other thing I have left to do is "mv" the new smaller pngs, overwriting the older ones. I'll look at those utilities after my script finishes. (In probably 2 days time. Yeah, they're a lot of photos.)

Re: pngnq script

Posted: 2010-11-08T03:15:47-07:00
by Xinerama
So I tried

Code: Select all

find . -type f -name '*.png' -print0 | xargs -0r mved -f *-nq8.= =.=
but it's not working.

I'm looking around but if you have an idea please let me know.
Thanks for all your help again.

Re: pngnq script

Posted: 2010-11-08T05:53:10-07:00
by Xinerama
Actually I found this command which works beautifully.

Code: Select all

find . -name '*.png' -exec bash -c 'mv "$1" "${1/%-nq8.png/.png}"' -- {} \;
Thanks to http://www.commandlinefu.com/commands/v ... ecursively

Re: pngnq script

Posted: 2010-11-08T16:35:05-07:00
by anthony
Xinerama wrote:So I tried

Code: Select all

find . -type f -name '*.png' -print0 | xargs -0r mved -f *-nq8.= =.=
but it's not working.
You can only use one '=' in each argument with "mved" which represents the wild card '*' pattern to transfer from one filename to the other. ASIDE: where did you get your version?

Also xargs places the filenames it receives at the end of the given command, EG:

Code: Select all

        xargs  -0r   command -opts
will run multiple commands of the form.

Code: Select all

        command -opts  file file file file file
whcih is not how "mved" works.

On the other hand it is how "mv_perl" accepts filenames.

Code: Select all

find . -type f -name '*.png' -print0 | xargs -0r mv_perl 's/-nq8//'
This uses the perl 's///' string substitution to remove the "-nq8" string from the filename.

Re: pngnq script

Posted: 2010-11-08T16:38:39-07:00
by anthony
Xinerama wrote:Actually I found this command which works beautifully.

Code: Select all

find . -name '*.png' -exec bash -c 'mv "$1" "${1/%-nq8.png/.png}"' -- {} \;
Thanks to http://www.commandlinefu.com/commands/v ... ecursively
WARNING: the find -exec will one that bash one line script once for each filename found.
Not only that the "find" command will pause while each command is run. It does not continue looking. Both of these reasons makes that method very slow.

See find -exec vs xargs
http://www.sunmanagers.org/pipermail/su ... 06255.html

This was in fact why xargs was invented.