54

I have a large set of JPEG pictures all with the same resolution. It would take too long to open each one inside the graphical interface of imagemagic or gimp.

How do I achieve each picture being rotated and saved as the same filename?

OrangeDog
  • 871
  • 6
  • 14
sharkant
  • 3,560
  • 10
  • 30
  • 46
  • 3
    See [here](http://www.imagemagick.org/Usage/photos/#orient). Beware however that re-encoding JPEG is generally lossy. – Satō Katsura May 17 '17 at 11:35
  • See also: [SuperUser: How to rotate images automatically, based on exif data](https://superuser.com/questions/36645/how-to-rotate-images-automatically-based-on-exif-data). – Gabriel Staples May 01 '21 at 01:04

4 Answers4

77

You can use the convert command:

convert input.jpg -rotate <angle in degrees> out.jpg

To rotate 90 degrees clockwise:

convert input.jpg -rotate 90 out.jpg

To save the file with the same name:

convert file.jpg -rotate 90 file.jpg

To rotate all files:

for photo in *.jpg ; do convert $photo -rotate 90 $photo ; done

Alternatively, you can also use the mogrify command line tools (the best tool) recommended by @don-crissti:

mogrify -rotate 90 *.jpg
GAD3R
  • 63,407
  • 31
  • 131
  • 192
20

For JPEG images and right-angle rotations, use jpegtran or exiftran, as they can rotate the images losslessly.

for f in *.jpg ; do 
    jpegtran -rotate 180 "$f" > "${f%.jpg}-rotated.jpg"
done

Or to rotate in-place:

for f in *.jpg ; do
    jpegtran -rotate 180 -outfile "$f" "$f"
done

exiftran also has the -a flag to automatically rotate the image based on what the EXIF orientation tag says.

ilkkachu
  • 133,243
  • 15
  • 236
  • 397
  • For counter-clockwise (left-angle) rotation with `jpegtran`, use `-rotate 270` and with exiftran use `-2`flag according to the manual. – Timo Mar 12 '18 at 19:47
  • `*.jpg` works under bash but under zshell it causes the error `jpegtran: can't open *.jpg for reading` but `*jpg` works for me in zshell. – Konrad Höffner Dec 28 '20 at 10:09
1

Note that the two other answers may provide different results depending on the EXIF Orientation : it seems that convert rotates with regards to the EXIF Orientation, while jpegtran just ignores the EXIF Orientation.

This observation led me to figure I actually needed to discard the EXIF Orientation, so I just used exiftool to discard EXIF data without further data loss (that's also what does jpegtran when no -rotate option is given, it seems) :

exiftool -all= -o outfile.jpg infile.jpg

I could have just removed the EXIF Orientation with

exiftool -Orientation= -o outfile.jpg infile.jpg

or modified it with

exiftool -n -Orientation=1 -o outfile.jpg infile.jpg

(for this later case you will need to read the FAQ to understand option -n, needed for exiftool to translate the -Orientation value, and the EXIF tags table).

0

This is an older question, however I found it whilst searching for a solution for this very task.

The problem with jpegtran is that it does rotate the image, but it discards all the EXIF header data.

exiftool keeps it, but it's not very handy to use.

Thus, I wrote a small script to rotate a JPEG image by 90°, keeping the EXIF header. Maybe someone may find this useful:

#!/bin/bash

orientation=$(exiftool -n -Orientation "$1")

if [[ "$?" != "0" ]]; then
    exit 1
fi

orientation=${orientation##*: }

if [[ "$orientation" == "1" ]]; then
    # 1 = Horizontal (normal)
    target="6"
elif [[ "$orientation" == "6" ]]; then
    # 6 = Rotate 90 CW
    target="3"
elif [[ "$orientation" == "3" ]]; then
    # 3 = Rotate 180
    target="8"
elif [[ "$orientation" == "8" ]]; then
    # 8 = Rotate 270 CW
    target="1"
else
    echo "Can't process orientation \"$orientation\""
    exit 1
fi

extension=${1/*./}
backup="${1%$extension*}orig.$extension"

mv "$1" "$backup" || exit 1

exiftool -n -Orientation=$target "$backup" -o "$1"