From ba6399cad14d816cafc44c25782d6a3153082ae4 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sun, 7 Jan 2024 19:34:27 +1100 Subject: [PATCH 1/3] Added PerspectiveTransform --- Tests/test_image_transform.py | 2 ++ docs/reference/ImageTransform.rst | 5 +++++ src/PIL/ImageTransform.py | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/Tests/test_image_transform.py b/Tests/test_image_transform.py index 15939ef647c..578a0a2967a 100644 --- a/Tests/test_image_transform.py +++ b/Tests/test_image_transform.py @@ -16,6 +16,8 @@ def test_sanity(self): transform = ImageTransform.AffineTransform(seq[:6]) im.transform((100, 100), transform) + transform = ImageTransform.PerspectiveTransform(seq[:8]) + im.transform((100, 100), transform) transform = ImageTransform.ExtentTransform(seq[:4]) im.transform((100, 100), transform) transform = ImageTransform.QuadTransform(seq[:8]) diff --git a/docs/reference/ImageTransform.rst b/docs/reference/ImageTransform.rst index 1278801821d..5b0a5ce49dc 100644 --- a/docs/reference/ImageTransform.rst +++ b/docs/reference/ImageTransform.rst @@ -19,6 +19,11 @@ The :py:mod:`~PIL.ImageTransform` module contains implementations of :undoc-members: :show-inheritance: +.. autoclass:: PerspectiveTransform + :members: + :undoc-members: + :show-inheritance: + .. autoclass:: ExtentTransform :members: :undoc-members: diff --git a/src/PIL/ImageTransform.py b/src/PIL/ImageTransform.py index 4f79500e64e..6aa82dadd9c 100644 --- a/src/PIL/ImageTransform.py +++ b/src/PIL/ImageTransform.py @@ -63,6 +63,26 @@ class AffineTransform(Transform): method = Image.Transform.AFFINE +class PerspectiveTransform(Transform): + """ + Define a perspective image transform. + + This function takes an 8-tuple (a, b, c, d, e, f, g, h). For each pixel + (x, y) in the output image, the new value is taken from a position + ((a x + b y + c) / (g x + h y + 1), (d x + e y + f) / (g x + h y + 1)) in + the input image, rounded to nearest pixel. + + This function can be used to scale, translate, rotate, and shear the + original image. + + See :py:meth:`.Image.transform` + + :param matrix: An 8-tuple (a, b, c, d, e, f, g, h). + """ + + method = Image.Transform.PERSPECTIVE + + class ExtentTransform(Transform): """ Define a transform to extract a subregion from an image. From ccdea48cf379fac585918001f304a7ab58448b96 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 8 Jan 2024 10:36:30 +1100 Subject: [PATCH 2/3] Added identity tests for Transform classes --- Tests/test_image_transform.py | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/Tests/test_image_transform.py b/Tests/test_image_transform.py index 578a0a2967a..f5d5ab70408 100644 --- a/Tests/test_image_transform.py +++ b/Tests/test_image_transform.py @@ -10,20 +10,25 @@ class TestImageTransform: def test_sanity(self): - im = Image.new("L", (100, 100)) - - seq = tuple(range(10)) - - transform = ImageTransform.AffineTransform(seq[:6]) - im.transform((100, 100), transform) - transform = ImageTransform.PerspectiveTransform(seq[:8]) - im.transform((100, 100), transform) - transform = ImageTransform.ExtentTransform(seq[:4]) - im.transform((100, 100), transform) - transform = ImageTransform.QuadTransform(seq[:8]) - im.transform((100, 100), transform) - transform = ImageTransform.MeshTransform([(seq[:4], seq[:8])]) - im.transform((100, 100), transform) + im = hopper() + + for transform in ( + ImageTransform.AffineTransform((1, 0, 0, 0, 1, 0)), + ImageTransform.PerspectiveTransform((1, 0, 0, 0, 1, 0, 0, 0)), + ImageTransform.ExtentTransform((0, 0) + im.size), + ImageTransform.QuadTransform( + (0, 0, 0, im.height, im.width, im.height, im.width, 0) + ), + ImageTransform.MeshTransform( + [ + ( + (0, 0) + im.size, + (0, 0, 0, im.height, im.width, im.height, im.width, 0), + ) + ] + ), + ): + assert_image_equal(im, im.transform(im.size, transform)) def test_info(self): comment = b"File written by Adobe Photoshop\xa8 4.0" From 931821688c0f9ef331097ac8b1358780eb82b21e Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 9 Jan 2024 12:22:25 +1100 Subject: [PATCH 3/3] Added release notes --- docs/releasenotes/10.3.0.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/releasenotes/10.3.0.rst b/docs/releasenotes/10.3.0.rst index 34afbe4b844..391068769fb 100644 --- a/docs/releasenotes/10.3.0.rst +++ b/docs/releasenotes/10.3.0.rst @@ -26,10 +26,12 @@ TODO API Additions ============= -TODO -^^^^ +Added PerspectiveTransform +^^^^^^^^^^^^^^^^^^^^^^^^^^ -TODO +:py:class:`~PIL.ImageTransform.PerspectiveTransform` has been added, meaning +that all of the :py:data:`~PIL.Image.Transform` values now have a corresponding +subclass of :py:class:`~PIL.ImageTransform.Transform`. Security ========