Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Computing > Digital Photography > ImageMagick and lossless JPEG rotation?

Reply
Thread Tools

ImageMagick and lossless JPEG rotation?

 
 
Jim Garrison
Guest
Posts: n/a
 
      09-30-2003
Can anyone tell me if ImageMagick does lossless 90-degree rotation?

TIA,
Jim Garrison


 
Reply With Quote
 
 
 
 
Mike Graham
Guest
Posts: n/a
 
      09-30-2003
In article <Ig6eb.171228$>, Jim Garrison wrote:

> Can anyone tell me if ImageMagick does lossless 90-degree rotation?


I don't believe that it does. There is a list of lossless rotators at
http://www.jpegclub.org, and it's not on the list. Mind you, there is only
*one* linux app on the list, and I'm finding it to be a pig to install on my
system, so I'd love to find out that I'm wrong about ImageMagick.

--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Mike Graham | Metalworker, rustic, part-time zealot.
mike 'at' metalmangler.com |
<http://www.metalmangler.com>| Caledon, Ontario, Canada

Lousy photographer with a really nice camera - Olympus C3020Zoom.
When that's broken I can use my Nikon D100
<http://www.metalmangler.com/photos/photos.htm>
<http://www.photo.net/shared/community-member?user_id=766040>
 
Reply With Quote
 
Mike Brodbelt
Guest
Posts: n/a
 
      09-30-2003
On Tue, 30 Sep 2003 05:58:23 -0400, Mike Graham wrote:

> In article <Ig6eb.171228$>, Jim Garrison
> wrote:
>
>> Can anyone tell me if ImageMagick does lossless 90-degree rotation?

>
> I don't believe that it does. There is a list of lossless rotators at
> http://www.jpegclub.org, and it's not on the list. Mind you, there is
> only *one* linux app on the list, and I'm finding it to be a pig to
> install on my system, so I'd love to find out that I'm wrong about
> ImageMagick.


AFAIK, you're not wrong - Imagemagick doesn't do lossless rotation. I use
jpegtran to do lossless rotation, which works very well. I have a shell
script which goes through each JPEG file in a directory, reads the
orientation tag from EXIF data, then calls jpegtran will appropriate
options to losslessly rotate the JPEG and preserve EXIF data. I can post
it if there's any interest.

Mike.

 
Reply With Quote
 
Richard Kaszeta
Guest
Posts: n/a
 
      09-30-2003
Mike Brodbelt <m.brodbelt@__NO_SPAM_PLEASE__coruscant.demon.co.u k> writes:
> AFAIK, you're not wrong - Imagemagick doesn't do lossless rotation. I use
> jpegtran to do lossless rotation, which works very well. I have a shell
> script which goes through each JPEG file in a directory, reads the
> orientation tag from EXIF data, then calls jpegtran will appropriate
> options to losslessly rotate the JPEG and preserve EXIF data. I can post
> it if there's any interest.


I wouldn't mind seeing the script.

--
Richard W Kaszeta

http://www.kaszeta.org/rich
 
Reply With Quote
 
Ron Olsen
Guest
Posts: n/a
 
      09-30-2003
m.brodbelt@__NO_SPAM_PLEASE__coruscant.demon.co.uk wrote:
>
> AFAIK, you're not wrong - Imagemagick doesn't do lossless rotation. I use
> jpegtran to do lossless rotation, which works very well. I have a shell
> script which goes through each JPEG file in a directory, reads the
> orientation tag from EXIF data, then calls jpegtran will appropriate
> options to losslessly rotate the JPEG and preserve EXIF data. I can post
> it if there's any interest.
>


jhead also does automatic rotation from the orientation tag, using jpegtran
to do the rotation:

http://www.sentex.net/~mwandel/jhead/

--
Ron Olsen

 
Reply With Quote
 
Mike Graham
Guest
Posts: n/a
 
      09-30-2003
In article <pan.2003.09.30.12.05.04.543810@__NO_SPAM_PLEASE__ coruscant.demon.co.uk>, Mike Brodbelt wrote:

> AFAIK, you're not wrong - Imagemagick doesn't do lossless rotation. I use
> jpegtran to do lossless rotation, which works very well. I have a shell
> script which goes through each JPEG file in a directory, reads the
> orientation tag from EXIF data, then calls jpegtran will appropriate
> options to losslessly rotate the JPEG and preserve EXIF data. I can post
> it if there's any interest.


Oooh! Oooh! I'm interested! Cool idea! In exchange I can offer you
something I found in the archives of the Nikon D100 mailing list. It's a
perl script written by one David Proulx, and it renames image files to the
date stored in the metadata, right down to the second. Very handy! The
date is done YYYYMMDD-hh:mm:ss so that files are sorted chronologically.
The readme for the file has no copyright info or anything, so I am confident
that it is public domain.

--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Mike Graham | Metalworker, rustic, part-time zealot.
mike 'at' metalmangler.com |
<http://www.metalmangler.com>| Caledon, Ontario, Canada

Lousy photographer with a really nice camera - Olympus C3020Zoom.
When that's broken I can use my Nikon D100
<http://www.metalmangler.com/photos/photos.htm>
<http://www.photo.net/shared/community-member?user_id=766040>
 
Reply With Quote
 
Mike Graham
Guest
Posts: n/a
 
      09-30-2003
In article <>, Ron Olsen wrote:

> jhead also does automatic rotation from the orientation tag, using jpegtran
> to do the rotation:
>
> http://www.sentex.net/~mwandel/jhead/


Wow. It looks like jhead does a *lot*.

--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Mike Graham | Metalworker, rustic, part-time zealot.
mike 'at' metalmangler.com |
<http://www.metalmangler.com>| Caledon, Ontario, Canada

Lousy photographer with a really nice camera - Olympus C3020Zoom.
When that's broken I can use my Nikon D100
<http://www.metalmangler.com/photos/photos.htm>
<http://www.photo.net/shared/community-member?user_id=766040>
 
Reply With Quote
 
Mike Brodbelt
Guest
Posts: n/a
 
      09-30-2003
On Tue, 30 Sep 2003 16:38:15 -0400, Mike Graham wrote:

> Oooh! Oooh! I'm interested! Cool idea! In exchange I can offer you
> something I found in the archives of the Nikon D100 mailing list. It's a
> perl script written by one David Proulx, and it renames image files to the
> date stored in the metadata, right down to the second. Very handy! The
> date is done YYYYMMDD-hh:mm:ss so that files are sorted chronologically.
> The readme for the file has no copyright info or anything, so I am confident
> that it is public domain.


Ok, I'm attaching it below. There are two parts - a shell script, and a
small c program which must be available on the path when you run the shell
script. You also need jpegtran installed and available. There may be other
ways to do this now - I've had this for ages, and it's always worked well
for me. I found it on as web forum somewhere ages ago, IIRR.

Enjoy,

Mike.


exifautotran.sh - shell script wrapper
==========8<==========8<==========8<==========8<== ========8<==========8<
# exifautotran[list of files]
#
# Transforms Exif files so that Orientation becomes 1
#
for i
do
case `jpegexiforient -n "$i"` in
1) transform="";;
2) transform="-flip horizontal";;
3) transform="-rotate 180";;
4) transform="-flip vertical";;
5) transform="-transpose";;
6) transform="-rotate 90";;
7) transform="-transverse";;
transform="-rotate 270";;
*) transform="";;
esac
if test -n "$transform"; then
echo Executing: jpegtran -copy all $transform $i
jpegtran -copy all $transform "$i" > tempfile
if test $? -ne 0; then
echo Error while transforming $i - skipped.
else
rm "$i"
mv tempfile "$i"
jpegexiforient -1 "$i" > /dev/null
fi
fi
done
==========8<==========8<==========8<==========8<== ========8<==========8<
jpegexiforient.c - compile with "gcc -O2 -o jpegexiforient jpegexiforient.c"
==========8<==========8<==========8<==========8<== ========8<==========8<
/*
* jpegexiforient.c
*
* This is a utility program to get and set the Exif Orientation Tag.
* It can be used together with jpegtran in scripts for automatic
* orientation correction of digital camera pictures.
*
* The Exif orientation value gives the orientation of the camera
* relative to the scene when the image was captured. The relation
* of the '0th row' and '0th column' to visual position is shown as
* below.
*
* Value | 0th Row | 0th Column
* ------+-------------+-----------
* 1 | top | left side
* 2 | top | rigth side
* 3 | bottom | rigth side
* 4 | bottom | left side
* 5 | left side | top
* 6 | right side | top
* 7 | right side | bottom
* 8 | left side | bottom
*
* For convenience, here is what the letter F would look like if it were
* tagged correctly and displayed by a program that ignores the orientation
* tag:
*
* 1 2 3 4 5 6 7 8
*
* 888888 888888 88 88 8888888888 88 88 8888888888
* 88 88 88 88 88 88 88 88 88 88 88 88
* 8888 8888 8888 8888 88 8888888888 8888888888 88
* 88 88 88 88
* 88 88 888888 888888
*
*/

#include <stdio.h>
#include <stdlib.h>

static FILE * myfile; /* My JPEG file */

static unsigned char exif_data[65536L];

/* Return next input byte, or EOF if no more */
#define NEXTBYTE() getc(myfile)

/* Error exit handler */
#define ERREXIT(msg) (exit(0))

/* Read one byte, testing for EOF */
static int
read_1_byte (void)
{
int c;

c = NEXTBYTE();
if (c == EOF)
ERREXIT("Premature EOF in JPEG file");
return c;
}

/* Read 2 bytes, convert to unsigned int */
/* All 2-byte quantities in JPEG markers are MSB first */
static unsigned int
read_2_bytes (void)
{
int c1, c2;

c1 = NEXTBYTE();
if (c1 == EOF)
ERREXIT("Premature EOF in JPEG file");
c2 = NEXTBYTE();
if (c2 == EOF)
ERREXIT("Premature EOF in JPEG file");
return (((unsigned int) c1) << + ((unsigned int) c2);
}

static const char * progname; /* program name for error messages */

static void
usage (void)
/* complain about bad command line */
{
fprintf(stderr, "jpegexiforient reads or writes the Exif Orientation Tag ");
fprintf(stderr, "in a JPEG Exif file.\n");

fprintf(stderr, "Usage: %s [switches] jpegfile\n", progname);

fprintf(stderr, "Switches:\n");
fprintf(stderr, " -n Do not output the trailing newline\n");
fprintf(stderr, " -1 .. -8 Set orientation value 1 .. 8\n");
}

/*
* The main program.
*/

int
main (int argc, char **argv)
{
int n_flag, set_flag;
unsigned int length, i;
int is_motorola; /* Flag for byte order */
unsigned int offset, number_of_tags, tagnum;

progname = argv[0];
if (progname == NULL || progname[0] == 0)
progname = "jpegexiforient"; /* in case C library doesn't provide it */

if (argc < 2) { usage(); return 0; }

n_flag = 0; set_flag = 0;

i = 1;
while (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'n':
n_flag = 1;
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
set_flag = argv[i][1] - '0';
break;
default:
usage(); return 0;
}
if (++i >= argc) { usage(); return 0; }
}

if (set_flag) {
if ((myfile = fopen(argv[i], "rb+")) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, argv[i]);
return 0;
}
} else {
if ((myfile = fopen(argv[i], "rb")) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, argv[i]);
return 0;
}
}

/* Read File head, check for JPEG SOI + Exif APP1 */
for (i = 0; i < 4; i++)
exif_data[i] = (unsigned char) read_1_byte();
if (exif_data[0] != 0xFF ||
exif_data[1] != 0xD8 ||
exif_data[2] != 0xFF ||
exif_data[3] != 0xE1)
return 0;

/* Get the marker parameter length count */
length = read_2_bytes();
/* Length includes itself, so must be at least 2 */
/* Following Exif data length must be at least 6 */
if (length <
return 0;
length -= 8;
/* Read Exif head, check for "Exif" */
for (i = 0; i < 6; i++)
exif_data[i] = (unsigned char) read_1_byte();
if (exif_data[0] != 0x45 ||
exif_data[1] != 0x78 ||
exif_data[2] != 0x69 ||
exif_data[3] != 0x66 ||
exif_data[4] != 0 ||
exif_data[5] != 0)
return 0;
/* Read Exif body */
for (i = 0; i < length; i++)
exif_data[i] = (unsigned char) read_1_byte();

if (length < 12) return 0; /* Length of an IFD entry */

/* Discover byte order */
if (exif_data[0] == 0x49 && exif_data[1] == 0x49)
is_motorola = 0;
else if (exif_data[0] == 0x4D && exif_data[1] == 0x4D)
is_motorola = 1;
else
return 0;

/* Check Tag Mark */
if (is_motorola) {
if (exif_data[2] != 0) return 0;
if (exif_data[3] != 0x2A) return 0;
} else {
if (exif_data[3] != 0) return 0;
if (exif_data[2] != 0x2A) return 0;
}

/* Get first IFD offset (offset to IFD0) */
if (is_motorola) {
if (exif_data[4] != 0) return 0;
if (exif_data[5] != 0) return 0;
offset = exif_data[6];
offset <<= 8;
offset += exif_data[7];
} else {
if (exif_data[7] != 0) return 0;
if (exif_data[6] != 0) return 0;
offset = exif_data[5];
offset <<= 8;
offset += exif_data[4];
}
if (offset > length - 2) return 0; /* check end of data segment */

/* Get the number of directory entries contained in this IFD */
if (is_motorola) {
number_of_tags = exif_data[offset];
number_of_tags <<= 8;
number_of_tags += exif_data[offset+1];
} else {
number_of_tags = exif_data[offset+1];
number_of_tags <<= 8;
number_of_tags += exif_data[offset];
}
if (number_of_tags == 0) return 0;
offset += 2;

/* Search for Orientation Tag in IFD0 */
for (; {
if (offset > length - 12) return 0; /* check end of data segment */
/* Get Tag number */
if (is_motorola) {
tagnum = exif_data[offset];
tagnum <<= 8;
tagnum += exif_data[offset+1];
} else {
tagnum = exif_data[offset+1];
tagnum <<= 8;
tagnum += exif_data[offset];
}
if (tagnum == 0x0112) break; /* found Orientation Tag */
if (--number_of_tags == 0) return 0;
offset += 12;
}

if (set_flag) {
/* Set the Orientation value */
if (is_motorola) {
exif_data[offset+2] = 0; /* Format = unsigned short (2 octets) */
exif_data[offset+3] = 3;
exif_data[offset+4] = 0; /* Number Of Components = 1 */
exif_data[offset+5] = 0;
exif_data[offset+6] = 0;
exif_data[offset+7] = 1;
exif_data[offset+8] = 0;
exif_data[offset+9] = (unsigned char)set_flag;
exif_data[offset+10] = 0;
exif_data[offset+11] = 0;
} else {
exif_data[offset+2] = 3; /* Format = unsigned short (2 octets) */
exif_data[offset+3] = 0;
exif_data[offset+4] = 1; /* Number Of Components = 1 */
exif_data[offset+5] = 0;
exif_data[offset+6] = 0;
exif_data[offset+7] = 0;
exif_data[offset+8] = (unsigned char)set_flag;
exif_data[offset+9] = 0;
exif_data[offset+10] = 0;
exif_data[offset+11] = 0;
}
fseek(myfile, (4 + 2 + 6 + 2) + offset, SEEK_SET);
fwrite(exif_data + 2 + offset, 1, 10, myfile);
} else {
/* Get the Orientation value */
if (is_motorola) {
if (exif_data[offset+8] != 0) return 0;
set_flag = exif_data[offset+9];
} else {
if (exif_data[offset+9] != 0) return 0;
set_flag = exif_data[offset+8];
}
if (set_flag > return 0;
}

/* Write out Orientation value */
if (n_flag)
printf("%c", '0' + set_flag);
else
printf("%c\n", '0' + set_flag);

/* All done. */
return 0;
}
==========8<==========8<==========8<==========8<== ========8<==========8<

 
Reply With Quote
 
C0mdrData
Guest
Posts: n/a
 
      10-01-2003
I definitely recommend Irfanview available free from www.irfanview.com

It has lossless Jpeg rotation, and great software to boot. Just DON'T use
the "rotate image" options on the Image menu. The lossless rotation is in
the options menu.

Bruce

"The human adventure is just beginning"

"Mike Graham" <> wrote in message
news:...
> In article <Ig6eb.171228$>, Jim Garrison

wrote:
>
> > Can anyone tell me if ImageMagick does lossless 90-degree rotation?

>
> I don't believe that it does. There is a list of lossless rotators at
> http://www.jpegclub.org, and it's not on the list. Mind you, there is

only
> *one* linux app on the list, and I'm finding it to be a pig to install on

my
> system, so I'd love to find out that I'm wrong about ImageMagick.
>
> --
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Mike Graham | Metalworker, rustic, part-time zealot.
> mike 'at' metalmangler.com |
> <http://www.metalmangler.com>| Caledon, Ontario, Canada
>
> Lousy photographer with a really nice camera - Olympus C3020Zoom.
> When that's broken I can use my Nikon D100
> <http://www.metalmangler.com/photos/photos.htm>
> <http://www.photo.net/shared/community-member?user_id=766040>



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
faststone lossless rotation bug? james Digital Photography 3 10-21-2009 08:22 AM
irfanview lossless jpg rotation dohduhdah@yahoo.com Digital Photography 22 10-01-2006 05:38 PM
Lossless rotation file size changes Keith Sheppard Digital Photography 2 02-04-2004 02:09 PM
Why is lossless rotation actually gainful rotation? Louise Digital Photography 19 02-02-2004 07:37 AM
Lossless rotation in Irfanview Terry Orchard Digital Photography 3 11-12-2003 08:53 AM



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57