def rotate(self, degrees, clockwise=False, resample_algorithm=nearest, resize_canvas=True): """ Returns the image obtained by rotating this image by the given number of degrees. Anticlockwise unless clockwise=True is given. """ # translate to the origin first, then rotate, then translate back transform = AffineTransform() transform = transform.translate(self.width * -0.5, self.height * -0.5) transform = transform.rotate(degrees, clockwise=clockwise) width, height = self.width, self.height if resize_canvas: # determine new width width, height = get_transformed_dimensions(transform, (0, 0, width, height)) transform = transform.translate(width * 0.5, height * 0.5) pixels = resample_algorithm.affine(self, transform, resize_canvas=resize_canvas) return self._copy(pixels)
def test_inverse(self): # identity inverse self.assertEqual(AffineTransform().inverse(), AffineTransform()) self.assertEqual( AffineTransform((2, 0, 0, 0, 2, 0, 0, 0, 2)).inverse(), AffineTransform((0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5))) # inverted A*0 = A/0, which is an error self.assertRaises(ValueError, (AffineTransform() * 0).inverse)
def test_constructor_3x3tuple(self): a = AffineTransform(((1, 2, 3), (4, 5, 6), (7, 8, 9))) self.assertEqual(a.matrix, (1, 2, 3, 4, 5, 6, 7, 8, 9)) self.assertRaises(ValueError, AffineTransform, ((1, 2, 3), (4, 5, 6))) self.assertRaises(ValueError, AffineTransform, ((1, 2), (3, 4), (5, 6)))
def test_rotate(self): a = AffineTransform() self.assertEqual(a.rotate(0), a) self.assertEqual(a.rotate(360), a) self.assertEqual(a.rotate(90), a.rotate(270, clockwise=True)) self.assertEqual(a.rotate(90), AffineTransform((0, -1, 0, 1, 0, 0, 0, 0, 1)))
def test_mult_vector(self): a = AffineTransform() * 2 self.assertEqual(a * (1, 2), (2, 4)) self.assertEqual(a * (1, 2, 3), (2, 4, 6)) self.assertRaises(ValueError, lambda: a * (1, )) self.assertRaises(ValueError, lambda: a * (1, 2, 3, 4)) self.assertRaises(ValueError, lambda: a * (1, 2, 3, 4)) self.assertRaises(TypeError, lambda: (1, 2, 3) * a)
def test_mult_scalar(self): a = AffineTransform() * 2 self.assertEqual(a.matrix, (2, 0, 0, 0, 2, 0, 0, 0, 2)) a = AffineTransform() * -1 self.assertEqual(a.matrix, (-1, 0, 0, 0, -1, 0, 0, 0, -1))
def test_translate(self): a = AffineTransform() t = a.translate(3, 4) self.assertEqual(t.matrix, (1, 0, 0, 0, 1, 0, 3, 4, 1)) self.assertEqual(t.translate(3, 4).matrix, (1, 0, 0, 0, 1, 0, 6, 8, 1))
def test_constructor_identity(self): a = AffineTransform() self.assertEqual(a.matrix, (1, 0, 0, 0, 1, 0, 0, 0, 1))
def test_chained_translate_rotate(self): a = AffineTransform() # translate by (3, 4). rotate by 90 degrees t = a.translate(3, 4).rotate(90) self.assertEqual(t.matrix, (0, -1, 0, 1, 0, 0, 4, -3, 1))
def test_div_affine(self): a = AffineTransform() * 8 b = AffineTransform() * 2 self.assertEqual((a / b).matrix, (4, 0, 0, 0, 4, 0, 0, 0, 4))
def test_mult_affine(self): a = AffineTransform() * 2 b = AffineTransform() * 3 self.assertEqual((a * b).matrix, (6, 0, 0, 0, 6, 0, 0, 0, 6))
def test_chained_translate_rotate_translate(self): a = AffineTransform() # translate by (3, 4). rotate by 90 degrees. then translate back. t = a.translate(3, 4).rotate(90).translate(-3, -4) self.assertEqual(t.matrix, (0, -1, 0, 1, 0, 0, 1, -7, 1))
def test_constructor_9tuple(self): a = AffineTransform((1, 2, 3, 4, 5, 6, 7, 8, 9)) self.assertEqual(a.matrix, (1, 2, 3, 4, 5, 6, 7, 8, 9)) self.assertRaises(ValueError, AffineTransform, (1, 2, 3, 4, 5, 6, 7, 8))
def test_rmult_scalar(self): a = 2 * AffineTransform() self.assertEqual(a.matrix, (2, 0, 0, 0, 2, 0, 0, 0, 2)) a = -1 * AffineTransform() self.assertEqual(a.matrix, (-1, 0, 0, 0, -1, 0, 0, 0, -1))
def test_div_scalar(self): a = AffineTransform() / 2 self.assertEqual(a.matrix, (0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5))
def resize(self, source, width, height, resize_canvas=True): transform = AffineTransform().scale( width / float(source.width), height / float(source.height) ) return self.affine(source, transform, resize_canvas=resize_canvas)