# How do I find out if a PDF image is flipped?

Q: I am trying to extract images from PDF files, and I need to know
the scale and if the image if flipped horizontally or vertically. I
have seen this:

However, in the case that the image is also rotated, this does not
work, unless the rotation is 180. Is there a way to determine if an
image has been flipped when it is also rotated?

Could you explain how this works, and also what exactly it returns?

// Get the average scaling (by X and Y) from a given Matrix.
double MatrixScale(pdftron.Common.Matrix2D m) {
double x = 0.707106781 * m.getA() + 0.707106781 * m.getB();
double y = 0.707106781 * m.getC() + 0.707106781 * m.getD();
return Math.Sqrt(x*x + y*y);
------
A: Since an image in PDF can be rotated using arbitrary angle (not
only using 90 degree multiples) you may need to refine you tests for a
flipped image.

The format of rotation matrix in PDF is as follows:

R(θ) =

> cos(θ) sin(θ) |
> -sin(θ) cos(θ) |
> 0 0 |

= | a b |
> c d |
> h v |

, which has the effect of rotating the coordinate system axes by an
angle θ counterclockwise

So a quick (and naive) test for a rotation matrix would be to check if
the mtx.m_c is negative (~ -1) and mtx.m_a is close to 0. A more
robust approach would decompose the affine transform to a product of
scaling, rotation, shear, and translation and would compute the
rotation angle from rotation matrix using atan2 function. For more,
information on this topic please see http://en.wikipedia.org/wiki/Rotation_matrix.

The MatrixScale() function referenced in your message, computes the
average scaling component of the matrix. The dimensions of an (non-
rotated) image on a PDF page would be
image.GetImageWidth()*MatrixScale(ctm),
image.GetImageHeight()*MatrixScale(ctm)). Another way to get a
bounding box for an image element is using element.GetBBox(ref rect).

Q: I currently need to know if the image has been flipped in either
direction, through the x-scale or y-scale factors being negative. I
apologize if I didn't make that clear.

However, your explanation above is of great value as well. It clears
up quite a bit.
---------------
A: If the determinant (http://en.wikipedia.org/wiki/Determinant) is
negative, the matrix is mirrored.
double det = mtx.m_a * mtx.m_d - mtx.m_b * mtx.m_c;
if(det<0) ... mirrored ...

More intuitively, if mtx.m_a is negative the image is flipped around
the X axis. If mtx.m_d is negative the image is flipped around the Y
axis, etc.