Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

this is my first post so I hope you'll be kind enough to forgive me if I make some formatting mistakes or else. This is one question I've had for quite some time and while looking for answers I have more questions arising. I was trying to find a way to compress pictures in a folder using convert in one command.

First I simply tried:

convert * -resize 50% Pic.jpg

However this returned the compressed pictures named Pic-0.jpg, Pic-1.jpg, etc. (I also tried $(find ".JPG") instead of * but this is expanded to the same. In order to have the formatting I wanted I tried:

convert * -resize 50% Pic_lorez_{1..3}.jpg

But this seemed to take the Pic_lorez_2.jpg and Pic3_lorez_3.jpg as input files, not output files. So following the advice of a friend, I tried:

find . -name "*.JPG" -exec convert {} -resize 50% {} \;

This compress all files under the same name but doesn't allow to put the name I want to these files (for example, Pic_lorez_{1,2,3,4,5,..100}.jpg).

Would xargs make it possible? Something along the lines of:

find . -name "*.JPG" | xargs convert ???

I couldn't figure out the proper syntax with xargs. I finally tried a direct pipe of find into convert but convert didn't seem to be able to work that way.

share|improve this question

5 Answers 5

convert writes to a different image file. To overwrite original image files use mogrify.

Single file:

mogrify -resize 50% Pic.jpg 

All .jpg files:

mogrify -resize 50% *.jpg
share|improve this answer

You could use this one liner: for img in $(ls *.jpg); do convert $img -resize 50% $img;done;

share|improve this answer

Try this:

SIZE=50 ; find -iname "*.jpg" | while read line ; do NF="$(echo $line | sed -r "s/(\.jpg|\.JPG)/_$SIZE\1/")" ; convert "$line" -resize $SIZE% "$NF" ; done

That's really not just one line. Here's an indented version:

SIZE=50
find -iname "*.jpg" | while read line ; do
  NF="$(echo $line | sed -r "s/(\.jpg|\.JPG)/_$SIZE\1/")"
  convert "$line" -resize $SIZE% "$NF"
done

You can adjust the value of SIZE to any other size, in percentage.

Please notice that after the first run, it will also take the already converted files as input files. You can skip files named like _NUMBER.jpg by modifying the find parameter, or you can also store the converted files somewhere else.

share|improve this answer

This script will do it for you!

Save it in a file and make the file executable with: chmod +x filename.

#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
C=0;
DES="./";       # Destination directory

for img in `find . -maxdepth 1 -mindepth 1 -iname '*.jpg' -type f`
do
    (( ++C ));
    NF="${DES}Pic_lorez_${C}.jpg";      # New file name
    convert $img -resize 50% $NF;
done

# restore $IFS
IFS=$SAVEIFS
  • Change the ./ to the directory where you want to put converted images, by default it will put them in current directory.
  • Change Pic_lorez_ to whatever name you want to give to converted files.
share|improve this answer

Use GNU Parallel:

find -iname "*.jpg" | parallel convert {} -resize 50% {.}_50pct.jpg

and get the added bonus of having all your CPU cores work in parallel and thus speed up the process.

10 seconds installation:

wget pi.dk/3 -qO - | sh -x

Watch the intro videos to learn more: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.