| AWARE [SYSTEMS] | Imaging expertise for the Delphi developer | |||||||
![]() |
TIFF and LibTiff Mailing List Archive | |||||||
LibTiff Mailing List
TIFF and LibTiff Mailing List Archive Contact
The TIFF Mailing List Homepage |
Thread2008.10.01 03:03 "Image Orientation tag and rotating images", by Richard NoldeConcerning rotating images in tiffcrop:
I've been working on the orientation tag issue for images rotated with
tiffcrop and I get two distinctly different results with a variety of
viewers. Below are the outputs from tiffinfo on the original image and
three versions rotated by 90, 180, and 270 degrees clockwise. The test
document has three pages but I am only showing the results for the first
page in each case.
My first question is whether I have made the correct adjustments to the
orientation tag for rotations of 90, 180, and 270 degrees clockwise.
Photoshop 7 on Winders displays the files as I would expect to see them,
which is the same as before I added the code to change the orientation
field in the output file. The Gimp 2.4.5 on Win2K and Fedora 8 display
them as I would expect as well. The same is true for Qfaxreader.
However, DIMIN Viewer n5 and 11 View on Winders and GThumb 2.7.10 on
Fedora 8 seem to be adding an additional mirroring operation to the
displayed image, eg. rotating by 90 degrees clockwise puts the top of
the original image on the right of the new image, but now the left and
right sides of the original, albeit rotated image to top and bottom
positions, are reversed so that I am seeing the text from the back side
as though the top and bottom of the rotated image are now reversed.
GQView 2.0.4 and Mirage 0.9.3 on Fedora 8 display R180 the same as the
original and R270 the same as R90, both of which are rotated 90 and then
mirrored vertically. Quickscan 1.0 Level3 and Quickscan 4.0 by Captiva
Software on Winders display all the images in the original orientation.
My second question is whether I should be updating the orientation tag
in addition to transforming the data or is that the cause of the
problem. Based on earlier posts to this list, it looks like an
either/or proposition but not both. I could offer the option to modify
the data or the tag or both as my current code does for inverting the
photometric interpretation tag for bilevel and grayscale images. My
concept is allow users to "fix" incorrectly stored images as well as to
modify the data when that is the desired result, but since this tag is
not always supported according to the TIFF 6.0 spec, I want the majority
of Linux viewers to be able to display the images correctly. It is only
since I added the new code to modify the orientation tag, that I have
seen the problem. Previously, all images were written out with the
orientation tag copied from the input file even though the data are
being reoriented and for all the images I have, this was
ORIENTATION_TOPLEFT. If I rotate the image 90 degrees in Photoshop 7 on
Winders, the orientation tag is no longer reported by tiffinfo.
Quickscan Pro rotates the image data but does not update the orientation
tag.
tiffinfo /tmp/test.tiff
TIFF Directory at offset 0x2738 (10040)
Subfile Type: multi-page document (2 = 0x2)
Image Width: 2552 Image Length: 4200
Resolution: 300, 300 pixels/inch
Bits/Sample: 1
Compression Scheme: CCITT Group 4
Photometric Interpretation: min-is-white
Thresholding: bilevel art scan
FillOrder: lsb-to-msb
Orientation: row 0 top, col 0 lhs
Samples/Pixel: 1
Rows/Strip: 4200
Min Sample Value: 0
Max Sample Value: 1
Planar Configuration: single image plane
Page Number: 0-3
Make: RICOH
Group 4 Options: (0 = 0x0)
tiffinfo /tmp/testR90.tiff
TIFF Directory at offset 0x30ce (12494)
Subfile Type: multi-page document (2 = 0x2)
Image Width: 4200 Image Length: 2552
Resolution: 300, 300 pixels/inch
Bits/Sample: 1
Compression Scheme: CCITT Group 4
Photometric Interpretation: min-is-white
Thresholding: bilevel art scan
FillOrder: lsb-to-msb
Orientation: row 0 lhs, col 0 bottom
Samples/Pixel: 1
Rows/Strip: 2552
Min Sample Value: 0
Max Sample Value: 1
Planar Configuration: single image plane
Page Number: 0-3
Make: RICOH
Group 4 Options: (0 = 0x0)
tiffinfo /tmp/testR180.tiff
TIFF Directory at offset 0x270e (9998)
Subfile Type: multi-page document (2 = 0x2)
Image Width: 2552 Image Length: 4200
Resolution: 300, 300 pixels/inch
Bits/Sample: 1
Compression Scheme: CCITT Group 4
Photometric Interpretation: min-is-white
Thresholding: bilevel art scan
FillOrder: lsb-to-msb
Orientation: row 0 bottom, col 0 rhs
Samples/Pixel: 1
Rows/Strip: 4200
Min Sample Value: 0
Max Sample Value: 1
Planar Configuration: single image plane
Page Number: 0-3
Make: RICOH
Group 4 Options: (0 = 0x0)
tiffinfo /tmp/testR270.tiff
TIFF Directory at offset 0x34b0 (13488)
Subfile Type: multi-page document (2 = 0x2)
Image Width: 4200 Image Length: 2552
Resolution: 300, 300 pixels/inch
Bits/Sample: 1
Compression Scheme: CCITT Group 4
Photometric Interpretation: min-is-white
Thresholding: bilevel art scan
FillOrder: lsb-to-msb
Orientation: row 0 rhs, col 0 top
Samples/Pixel: 1
Rows/Strip: 2552
Min Sample Value: 0
Max Sample Value: 1
Planar Configuration: single image plane
Page Number: 0-3
Make: RICOH
Group 4 Options: (0 = 0x0)
Here is the piece of code that I am testing to assign the new
orientation value. Rotation is the clockwise value being applied to the
image data itself and image->orientation is initially the value read
from the source image and it gets reset to the new value below before
being written back to the output file. If it turns out that I should not
update the orientation tag when reordering the image pixels, I can make
this code conditional based on the users request to update the tag OR to
update only the tag.
switch (rotation)
{
case 90:
switch (image->orientation)
{
case ORIENTATION_TOPLEFT: /* 1, row 0 top, col 0 lhs */
image->orientation += 2;
case ORIENTATION_TOPRIGHT: /* 2, row 0 top, col 0 rhs */
image->orientation += 2;
case ORIENTATION_BOTRIGHT: /* 3, row 0 bottom, col 0 rhs */
image->orientation += 2;
case ORIENTATION_BOTLEFT: /* 4, row 0 bottom, col 0 lhs */
image->orientation += 1;
break;
case ORIENTATION_RIGHTTOP: /* 6, row 0 rhs, col 0 top */
case ORIENTATION_LEFTBOT: /* 8, row 0 lhs, col 0 bottom */
image->orientation -= 2;
case ORIENTATION_LEFTTOP: /* 5, row 0 lhs, col 0 top */
case ORIENTATION_RIGHTBOT: /* 7, row 0 rhs, col 0 bottom */
image->orientation -= 3;
break;
default: image->orientation = ORIENTATION_TOPLEFT;
}
break;
case 180:
switch (image->orientation)
{
case ORIENTATION_TOPLEFT: /* 1, row 0 top, col 0 lhs */
case ORIENTATION_TOPRIGHT: /* 2, row 0 top, col 0 rhs */
case ORIENTATION_LEFTTOP: /* 5, row 0 lhs, col 0 top */
case ORIENTATION_RIGHTTOP: /* 6, row 0 rhs, col 0 top */
image->orientation += 2;
break;
case ORIENTATION_BOTRIGHT: /* 3, row 0 bottom, col 0 rhs */
case ORIENTATION_BOTLEFT: /* 4, row 0 bottom, col 0 lhs */
case ORIENTATION_RIGHTBOT: /* 7, row 0 rhs, col 0 bottom */
case ORIENTATION_LEFTBOT: /* 8, row 0 lhs, col 0 bottom */
image->orientation -= 2;
break;
default: image->orientation = ORIENTATION_TOPLEFT;
}
break;
case 270:
switch (image->orientation)
{
case ORIENTATION_TOPLEFT: /* 1, row 0 top, col 0 lhs */
case ORIENTATION_BOTRIGHT: /* 3, row 0 bottom, col 0 rhs */
image->orientation += 2;
case ORIENTATION_TOPRIGHT: /* 2, row 0 top, col 0 rhs */
case ORIENTATION_BOTLEFT: /* 4, row 0 bottom, col 0 lhs */
image->orientation += 3;
break;
case ORIENTATION_LEFTBOT: /* 8, row 0 lhs, col 0 bottom */
image->orientation -= 2;
case ORIENTATION_RIGHTBOT: /* 7, row 0 rhs, col 0 bottom */
image->orientation -= 2;
case ORIENTATION_RIGHTTOP: /* 6, row 0 rhs, col 0 top */
image->orientation -= 2;
case ORIENTATION_LEFTTOP: /* 5, row 0 lhs, col 0 top */
image->orientation -= 1;
break;
default: image->orientation = ORIENTATION_TOPLEFT;
}
break;
default: TIFFError("rotateImage", "Invalid rotation angle %d",
rotation);
return (-1);
}
Richard Nolde
Tiffcrop author
|
|||||||