CTM (Current Transformation Matrix) for images


I'm working on a module that will apply a transform (scaling,
rotation, translation, skew) to an image file exported from the PDF.
The transform is intended to ensure that the extracted image has the
same appearance as the displayed PDF.

According to the spec, PDF matrix transformations specify the
conversion from the transformed coordinate system to the original
(untransformed) coordinate system.

Therefore, I'm assuming that the CTM returned by:

pdftron::Common::Matrix2D ctm = m_pElement->GetCTM();

returns a transformation matrix to map an element from a transformed
coordinate system to an untransformed system.

We want to export an image from the PDF and apply a transform to the
original image in order to match the display appearance of the PDF. Do
we need to apply the inverse transform (from the CTM of the image)? If
so, does PDFNet provide any support for finding the inverse matrix or
will we need to provide this function? Or is there another approach?


Does PDFNet provide any support for finding the inverse matrix or will we need to provide this function?

To compute the matrix inverse you could use:

pdftron::Common::Matrix2D ctm = m_pElement->GetCTM();
pdftron::Common::Matrix2D inv = ctm.Inverse();

Btw, the CTM maps the 1x1 unit square to the image parallelogram (i.e.
as the image appears on page). So the original PDF image is always 1x1
point and is 'stretched' and positioned using the CTM.

I follow that the ctm defines the transformation from a 1x1 point
square to the PDF coordinate system.

I was wondering if it is possible to derive a single affine transform
(given the dimensions of the extracted image and the ctm) that when
applied to the extracted image will result in it having the same
rotation, scale and skew as the image displayed in the PDF.

This probably isn't possible (or at least not straightforward!). Is the
alternative to simply examine the ctm values and apply one or more
transformations in sequence?

For example, the rotation angle of the extracted image can be found
from the ctm.m_b and ctm.m_c values. Similarly, if the ctm.m_a and
ctm.m_d values are both equal to 100 and the extracted image has a
height and with of 50 the scalefactor is 2. (Assuming a 1:1 mapping
between pixels and points). The extracted image would then be scaled by
2 in order to have the same appearance as the PDF display.

This is the approach I was following but wanted to check that there
wasn't an alternative method. BTW: Is there a recommended order to the
(the PDF spec mentions translate then rotate, and finally scale/skew).

This should be possible. You only need to concatenate the matrix that
maps pixel/image space to the 'unit square' with the CTM (Current
Transformation Matrix). Something along the following lines:

Common::Matrix2D mtx = image_element->GetCTM() *
Common::Matrix2D(1.0/width, 0, 0, 1.0/height, 0, 0);