Welcome to pillow_affine’s documentation!¶
pillow_affine
provides affine transformation utilities for Pillow
. While
Pillow
includes functionality for affine transformations
from PIL import Image
image = Image.open(...)
image.transform(image.size, Image.AFFINE, data=None)
the data
parameter is not well documented. Even if you are familiar with
affine transformations, it is inconvenient to use. pillow_affine
can help
with that by providing an intuitive and convenient interface:
from PIL import Image
from pillow_affine import transforms
image = Image.open(...)
transform = transforms.Rotate(30.0)
transform_params = transform.extract_transform_params(image.size)
image.transform(*transform_params)
pillow_affine
requires Python 3.6 or later. The code lives on
GitHub and is licensed under the
3-Clause BSD License.
Getting started¶
Installation¶
pillow_affine
is a proper Python package and listed on
PyPI. To install the latest stable
version run
pip install pillow_affine
To install the latest unreleased version from source run
git clone https://github.com/pmeier/pillow_affine
cd pillow_affine
pip install .
Installation for developers¶
If you want to contribute to pyimagetest
please install from source with the
[dev]
extra in order to install all required development tools.
git clone https://github.com/pmeier/pyimagetest
cd pyimagetest
pip install .[dev]
Coordinate system¶
Warning
pillow_affine
uses a different, presumably more intuitive, coordinate
system than Pillow
:
Property |
|
|
---|---|---|
origin, i.e. (0.0, 0.0) |
top-left |
bottom-left |
horizontal positive direction |
rightwards |
rightwards |
vertical positive direction |
downwards |
upwards |
Usage examples¶
Every affine transformation is build from 4 ElementaryTransform
s:
To create a more complex transformation these
ElementaryTransform
s can be chained together
with a ComposedTransform
The following examples showcase the functionality of pillow_affine
based on
the following image:

Note
The above image can be downloaded here and is cleared for unrestricted usage.
Shear
¶
from pillow_affine import Shear
transform1 = Shear(30.0)
transform2 = Shear(30.0, clockwise=True)
transform3 = Shear(30.0, center=(0.0, 0.0))



Rotate
¶
from pillow_affine import Rotate
transform1 = Rotate(30.0)
transform2 = Rotate(30.0, clockwise=True)
transform3 = Rotate(30.0, center=(0.0, 0.0))



Scale
¶
from pillow_affine import Scale
transform1 = Scale(2.0)
transform2 = Scale((0.3, 1.0))
transform3 = Scale(0.5, center=(0.0, 0.0))



Translate
¶
from pillow_affine import Translate
transform1 = Translate((100.0, 50.0))
transform2 = Translate((100.0, 50.0), inverse=True)


ComposedTransform
¶
from pillow_affine import Shear, Rotate, Scale, Translate, ComposedTransform
transform1 = ComposedTransform(
Shear(45.0),
Rotate(30.0),
Scale(0.7),
)
transform2 = ComposedTransform(
Scale((0.3, 0.7)),
Rotate(70.0, clockwise=True),
Translate((50.0, 20.0))
)


expand
¶
from pillow_affine import Shear
transform = Shear(30.0)
transform_params1 = transform.extract_transform_params(size)
transform_params2 = transform.extract_transform_params(size, expand=True)


Reference¶
pillow_affine package¶
Submodules¶
pillow_affine.matrix module¶
-
pillow_affine.matrix.
shearing_matrix
(angle, clockwise=False)¶ Creates an affine horizontal shearing matrix in the form
\[\begin{split}\mathrm{\mathbf{S}} = \begin{pmatrix} 1 & - \sin \varphi & 0 \\ 0 & \cos \varphi & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} = \begin{pmatrix} a & b & c \\ d & e & f \\ 0 & 0 & 1 \\ \end{pmatrix}\end{split}\]- Parameters
angle (
float
) – Angle \(\varphi\) in degrees.clockwise (
bool
) – IfTrue
, the shearing will be performed clockwise. Defaults toFalse
.
- Return type
Tuple
[float
,float
,float
,float
,float
,float
]- Returns
Parameters \(a\), \(b\), \(c\), \(d\), \(e\), \(f\).
-
pillow_affine.matrix.
rotation_matrix
(angle, clockwise=False)¶ Creates an affine rotation matrix in the form
\[\begin{split}\mathrm{\mathbf{R}} = \begin{pmatrix} \cos \varphi & - \sin \varphi & 0 \\ \sin \varphi & \cos \varphi & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} = \begin{pmatrix} a & b & c \\ d & e & f \\ 0 & 0 & 1 \\ \end{pmatrix}\end{split}\]- Parameters
angle (
float
) – Angle \(\varphi\) in degrees.clockwise (
bool
) – IfTrue
, the rotation will be performed clockwise. Defaults toFalse
.
- Return type
Tuple
[float
,float
,float
,float
,float
,float
]- Returns
Parameters \(a\), \(b\), \(c\), \(d\), \(e\), \(f\).
-
pillow_affine.matrix.
scaling_matrix
(factor)¶ Creates an affine scaling matrix in the form
\[\begin{split}\mathrm{\mathbf{C}} = \begin{pmatrix} c_\text{horz} & & 0 \\ 0 & c_\text{vert} & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} = \begin{pmatrix} a & b & c \\ d & e & f \\ 0 & 0 & 1 \\ \end{pmatrix}\end{split}\]- Parameters
factor (
Union
[float
,Tuple
[float
,float
]]) – Horizontal and vertical scaling factors (\(c_\text{horz}\), \(c_\text{vert}\)). If scalar, the same factor is used for both directions.- Return type
Tuple
[float
,float
,float
,float
,float
,float
]- Returns
Parameters \(a\), \(b\), \(c\), \(d\), \(e\), \(f\).
-
pillow_affine.matrix.
translation_matrix
(translation, inverse=False)¶ Creates an affine scaling matrix in the form
\[\begin{split}\mathrm{\mathbf{T}} = \begin{pmatrix} 1 & 0 & t_\text{horz} \\ 0 & 1 & t_\text{vert} \\ 0 & 0 & 1 \\ \end{pmatrix} = \begin{pmatrix} a & b & c \\ d & e & f \\ 0 & 0 & 1 \\ \end{pmatrix}\end{split}\]- Parameters
translation (
Tuple
[float
,float
]) – Horizontal and vertical translation. (\(t_\text{horz}\), \(t_\text{vert}\))inverse (
bool
) – IfTrue
, the translation will be performed in the opposite direction. Defaults toFalse
.
- Return type
Tuple
[float
,float
,float
,float
,float
,float
]- Returns
Parameters \(a\), \(b\), \(c\), \(d\), \(e\), \(f\).
pillow_affine.transforms module¶
-
class
pillow_affine.transforms.
AffineTransform
¶ Bases:
abc.ABC
ABC for all affine transformations.
-
extract_transform_params
(size, expand=False)¶ Extracts the transformation parameters that need to be passed to Image.transform() for the affine transformation. An simple call might look like:
from PIL import Image from pillow_affine import transforms image = Image.open(...) transform = transforms.Rotate(30.0) transform_params = transform.extract_transform_params(image.size) transformed_image = image.transform(*transform_params)
- Parameters
size (
Tuple
[int
,int
]) – Image size (width, height).expand (
bool
) – IfTrue
, expands the canvas to hold the complete transformed motif. Defaults toFalse
.
Note
If you use the
expand
flag the motif is centered on the canvas and thus any final translation is removed.- Return type
Tuple
[Tuple
[int
,int
],int
,Tuple
[float
,float
,float
,float
,float
,float
]]- Returns
size
,method
, anddata
parameters for Image.transform().
-
-
class
pillow_affine.transforms.
Shear
(angle, clockwise=False, center=None)¶ Bases:
pillow_affine.transforms.ElementaryTransform
Affine horizontal shearing transformation.
- Parameters
angle (
float
) – Shearing angle in degrees.clockwise (
bool
) – IfTrue
, the shearing will be performed clockwise. Defaults toFalse
.center (
Optional
[Tuple
[float
,float
]]) – Optional center of the shearing. Defaults to the center of the image.
-
class
pillow_affine.transforms.
Rotate
(angle, clockwise=False, center=None)¶ Bases:
pillow_affine.transforms.ElementaryTransform
Affine rotation transformation.
- Parameters
angle (
float
) – Rotation angle in degrees.clockwise (
bool
) – IfTrue
, the rotation will be performed clockwise. Defaults toFalse
.center (
Optional
[Tuple
[float
,float
]]) – Optional center of the rotation. Defaults to the center of the image.
-
class
pillow_affine.transforms.
Scale
(factor, center=None)¶ Bases:
pillow_affine.transforms.ElementaryTransform
Affine scaling transformation
- Parameters
factor (
Union
[float
,Tuple
[float
,float
]]) – Horizontal and vertical scaling factors. If scalar, the same factor is used for both directions.center (
Optional
[Tuple
[float
,float
]]) – Optional center of the scaling. Defaults to the center of the image.
-
class
pillow_affine.transforms.
Translate
(translation, inverse=False)¶ Bases:
pillow_affine.transforms.ElementaryTransform
Affine translation transformation
- Parameters
translation (
Tuple
[float
,float
]) – Horizontal and vertical translation.inverse (
bool
) – IfTrue
, the translation will be performed in the opposite direction. Defaults toFalse
.
-
class
pillow_affine.transforms.
ComposedTransform
(*transforms)¶ Bases:
pillow_affine.transforms.AffineTransform
Composed affine transformation by chaining multiple
AffineTransform
s together. An simple example might look like:from PIL import Image from pillow_affine import transforms image = Image.open(...) transform = transforms.ComposedTransform( transforms.Rotate(30.0), transforms.Translate((50.0, 100.0)) ) transform_params = transform.extract_transform_params(image.size) transformed_image = image.transform(*transform_params)
- Parameters
transforms (
AffineTransform
) – IndividualAffineTransform
s.
pillow_affine.utils module¶
-
pillow_affine.utils.
Coordinate
¶ alias of
typing.Tuple
-
pillow_affine.utils.
Matrix
¶ alias of
typing.Tuple
-
pillow_affine.utils.
matmul
(matrix1, matrix2)¶ Matrix product
\[\begin{split}\begin{pmatrix} a_1 & b_1 & c_1 \\ d_1 & e_1 & f_1 \\ 0 & 0 & 1 \\ \end{pmatrix} \cdot \begin{pmatrix} a_2 & b_2 & c_2 \\ d_2 & e_2 & f_2 \\ 0 & 0 & 1 \\ \end{pmatrix} = \begin{pmatrix} a & b & c \\ d & e & f \\ 0 & 0 & 1 \\ \end{pmatrix}\end{split}\]- Parameters
matrix1 (
Tuple
[float
,float
,float
,float
,float
,float
]) – Parameters \(a_1\), \(b_1\), \(c_1\), \(d_1\), \(e_1\), \(f_1\).matrix2 (
Tuple
[float
,float
,float
,float
,float
,float
]) – Parameters \(a_2\), \(b_2\), \(c_2\), \(d_2\), \(e_2\), \(f_2\).
- Return type
Tuple
[float
,float
,float
,float
,float
,float
]- Returns
Parameters \(a\), \(b\), \(c\), \(d\), \(e\), \(f\).
-
pillow_affine.utils.
left_matmuls
(*matrices)¶ Matrix product of \(N\) matrices from the left
\[\begin{split}\begin{pmatrix} a_N & b_N & c_N \\ d_N & e_N & f_N \\ 0 & 0 & 1 \\ \end{pmatrix} \cdot \quad\dots\quad \cdot \begin{pmatrix} a_n & b_n & c_n \\ d_n & e_n & f_n \\ 0 & 0 & 1 \\ \end{pmatrix} \quad\dots\quad \cdot \begin{pmatrix} a_1 & b_1 & c_1 \\ d_1 & e_1 & f_1 \\ 0 & 0 & 1 \\ \end{pmatrix} = \begin{pmatrix} a & b & c \\ d & e & f \\ 0 & 0 & 1 \\ \end{pmatrix}\end{split}\]- Parameters
*matrices – Parameters \(a_n\), \(b_n\), \(c_n\), \(d_n\), \(e_n\), \(f_n\) of each matrix.
- Return type
Tuple
[float
,float
,float
,float
,float
,float
]- Returns
Parameters \(a\), \(b\), \(c\), \(d\), \(e\), \(f\).
-
pillow_affine.utils.
matinv
(matrix)¶ Matrix inverse
\[\begin{split}\begin{pmatrix} a & b & c \\ d & e & f \\ 0 & 0 & 1 \\ \end{pmatrix}^{-1} = \begin{pmatrix} a^\prime & b^\prime & c^\prime \\ d^\prime & e^\prime & f^\prime \\ 0 & 0 & 1 \\ \end{pmatrix}\end{split}\]- Parameters
matrix (
Tuple
[float
,float
,float
,float
,float
,float
]) – Parameters \(a\), \(b\), \(c\), \(d\), \(e\), \(f\).- Return type
Tuple
[float
,float
,float
,float
,float
,float
]- Returns
Parameters \(a^\prime\), \(b^\prime\), \(c^\prime\), \(d^\prime\), \(e^\prime\), \(f^\prime\).
-
pillow_affine.utils.
deg2rad
(angle_in_deg)¶ Converts an angle from degrees to radians
- Parameters
angle_in_deg (
float
) – Angle in degrees.- Return type
float
- Returns
Angle in radians.
-
pillow_affine.utils.
transform_coordinate
(coordinate, matrix)¶ Transforms a
coordinate
based on an affinematrix
\[\begin{split}\begin{pmatrix} a & b & c \\ d & e & f \\ 0 & 0 & 1 \\ \end{pmatrix} \cdot \begin{pmatrix} x \\ y \\ 1 \\ \end{pmatrix} = \begin{pmatrix} x^\prime \\ y^\prime \\ 1 \\ \end{pmatrix}\end{split}\]- Parameters
coordinate (
Tuple
[float
,float
]) – Coordinate (\(x\), \(y\)).matrix (
Tuple
[float
,float
,float
,float
,float
,float
]) – Affine parameters \(a\), \(b\), \(c\), \(d\), \(e\), \(f\).
- Return type
Tuple
[float
,float
]- Returns
Transformed coordinate (\(x^\prime\), \(y^\prime\)).