Hi all,
its not so much a problem as I really cant quite get my head round it. What I am attempting to do is run a cron job which looks through a specific directory of images and then uses convert from the image magic package to compress the image if it is over a certain size.

Find all command to ls -lh all files > 300kb in size:

$ find . -size +300k -type f -exec ls -lh {} \;

ImageMagicks convert command to compress a single file(compress JPEG/quality 75).

$ convert -compress JPEG -quality 75 image.jpg image.jpg

So how can we combine these two commands? We can either do a convert using a wildcard which I am unsure even exists in converts functionality or when performing find we pass across the value of the filename, something like:

$ find . -size +300k -type f -exec convert -compress JPEG -quality 75 $filename $filename {} \;

I have already experimented with wildcard operations to no avail.

Any help you can offer would be massively appreciated.

    Hi dalecosp, thanks for replying. Yes xargs is available.

      You might be able to use it, then.

      find . -name foobar -print | xargs /bin/cp /tmp

      If I've got your commands accurate, then:

      find . -size +30k -type f -print0 | xargs -I {} -0 -L 1 convert -compress JPEG -quality 75 {} {}

      Test first, please --- no guarantees 😉

        Alas it does not work.

        I am testing with +840k as this will produce only a single file, easier for testing. I also tested using a much lower value and the results were the same.

        IgglePiggle@HOSTBOX:~/vhosts/www/web/images/project_large_test$ find . -size +840k -type f -print0 | xargs -I {} -0 -L 1 convert -compress JPEG -quality 75 {} {}.

        Produced the following error which would dictate that either the input value or output value is not set.

        convert: unable to open image `{}': No such file or directory @ blob.c/OpenBlob/2480.
        convert: missing an image filename `./example-image.jpg' @ convert.c/ConvertImageCommand/2838.

          Just had a little thought, can {} be given an abitrary name, for example {bob} and then use it later within -quality 75 {bob} {bob}. I experimented with this but my knowledge of xargs is limited and it just produced errors which would indicate that either my syntax is wrong or it can not be done.

            I'd say it's because putting the [font=monospace]|[/font]pipe in to separate the [font=monospace]find[/font] command from the [font=monospace]convert[/font] command means that [font=monospace]{}[/font] placeholder is no longer part of the [font=monospace]find[/font] - and of course [font=monospace]convert[/font] has no idea what to do with it.

              Well, it never was part of find. I tested on FreeBSD - maybe my xargs isn't portable enough for all Nixen. AFAIK, though, I didn't use any FreeBSD-specific calls there. I have CentOS here@work, I'll try another test case on that (assuming it has ImageMagick).

                editCorrection, it doesn't seem to work on my CentOS, but does in FreeBSD. I'll see if I can give a few minutes to figuring out why.

                  Hi dalecosp, thanks for the response. I have tested it on Rhel 6.2, Ubuntu Server 10.04 and CenOS 5.4 all with the same results.

                  I understand that its a little frustrating to help someone beyond the call of duty but I really appreciate it.

                    Eureka!

                    GNU's xargs is just a little dumber than FreeBSD's. Try this instead:

                    find . -size +30k -type f -print0 | xargs -0 -L 1 -I {} convert -compress JPEG -quality 75 {} {}

                    Putting the -I param last in GNU xargs seems to do the trick here, on CentOS. 😃

                      Hi dalecosp, thanks very much for all your help. Just tried and it works like a charm.

                      I will mark this thread resolved but for anyone who comes across this thread at any point in the future who needs similar assistance here is a quick run down.

                      This command:

                      find . -size +100k -type f -print0 | xargs -0 -L 1 -I {} convert -compress JPEG -quality 75 {} {}

                      Will find all images in the current directory who's size is greater 100Kb in size and then by the use of xargs pass the filenames over to convert which will compress the images.

                      In the example above I am compressing with the JPEG compression using a quality setting of 75 which is quite heavily compressed, the range is 1 to 100 so use at your discretion.

                        You're most welcome, Iggle. 🙂

                        If any GNU-developer types come 'round here in the future, methinks that your xargs(1) probably should not care whether or not -I comes last. 😉 😉

                          Hmm, incidentally, CentOS 5.8 is using GNU's findutils 4.2.27 ... which dates from 2005 :eek:

                          Iggle, what does "xargs --version" say on your system, if you don't mind my asking?

                          It's possible, I guess, that the behavior has been fixed in later versions of GNU xargs(1)....

                            CentOS 5.4 which is fairly old in itself is using 4.2.27.

                              Thanks. What about your Rhel and Ubuntu boxen? What version of xargs is there?

                                I've confirmed that this exists in GNU xargs(1)/findutils through 4.4.2 (2009), which is the last public release I see on their FTP mirrors.

                                A bug is filed at https://savannah.gnu.org/bugs/?36452

                                Note that there appears to have been much work done in findutils since 2009, so this might be fixed, but lots of people (most users?) could be using the older version (obviously we are). For the archives' sake, I'll try and remember to post back here in the event anything happens with the bug report.

                                  OK, my bad. Apparently in Linux, "-I" implies both "-x" and "-L 1" (it only implies "-x" in the BSD's), and therefore the -I and -L switches are incompatible; which means you can remove the "-L 1" portion of the command in Linuxen and still have this work.

                                  Happy Day! 😃

                                    Write a Reply...