def test_linear_gradient_wrong_mode(self): # Arrange wrong_mode = "RGB" # Act / Assert with pytest.raises(ValueError): Image.linear_gradient(wrong_mode)
def test_identities(self): g = Image.linear_gradient("L") im = Image.merge( "RGB", [g, g.transpose(Image.ROTATE_90), g.transpose(Image.ROTATE_180)]) # Fast test with small cubes for size in [2, 3, 5, 7, 11, 16, 17]: assert_image_equal( im, im._new( im.im.color_lut_3d("RGB", Image.LINEAR, *self.generate_identity_table(3, size))), ) # Not so fast assert_image_equal( im, im._new( im.im.color_lut_3d( "RGB", Image.LINEAR, *self.generate_identity_table(3, (2, 2, 65)))), )
def test_apply(self): lut = ImageFilter.Color3DLUT.generate(5, lambda r, g, b: (r, g, b)) g = Image.linear_gradient('L') im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90), g.transpose(Image.ROTATE_180)]) self.assertEqual(im, im.filter(lut))
def test_numpy_formats(self): g = Image.linear_gradient("L") im = Image.merge( "RGB", [g, g.transpose(Image.ROTATE_90), g.transpose(Image.ROTATE_180)] ) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut.table = numpy.array(lut.table, dtype=numpy.float32)[:-1] with self.assertRaisesRegex(ValueError, "should have table_channels"): im.filter(lut) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut.table = numpy.array(lut.table, dtype=numpy.float32).reshape((7 * 9 * 11), 3) with self.assertRaisesRegex(ValueError, "should have table_channels"): im.filter(lut) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut.table = numpy.array(lut.table, dtype=numpy.float16) self.assert_image_equal(im, im.filter(lut)) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut.table = numpy.array(lut.table, dtype=numpy.float32) self.assert_image_equal(im, im.filter(lut)) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut.table = numpy.array(lut.table, dtype=numpy.float64) self.assert_image_equal(im, im.filter(lut)) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut.table = numpy.array(lut.table, dtype=numpy.int32) im.filter(lut) lut.table = numpy.array(lut.table, dtype=numpy.int8) im.filter(lut)
def test_apply(self): lut = ImageFilter.Color3DLUT.generate(5, lambda r, g, b: (r, g, b)) g = Image.linear_gradient("L") im = Image.merge( "RGB", [g, g.transpose(Image.ROTATE_90), g.transpose(Image.ROTATE_180)] ) self.assertEqual(im, im.filter(lut))
def test_linear_gradient_wrong_mode(self): # Arrange wrong_mode = "RGB" # Act / Assert self.assertRaises(ValueError, lambda: Image.linear_gradient(wrong_mode)) return
def test_copy_alpha_channel(self): g = Image.linear_gradient('L') im = Image.merge('RGBA', [g, g.transpose(Image.ROTATE_90), g.transpose(Image.ROTATE_180), g.transpose(Image.ROTATE_270)]) self.assert_image_equal(im, im._new( im.im.color_lut_3d('RGBA', Image.LINEAR, *self.generate_identity_table(3, 17))))
def test_identities_4_channels(self): g = Image.linear_gradient('L') im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90), g.transpose(Image.ROTATE_180)]) # Red channel copied to alpha self.assert_image_equal( Image.merge('RGBA', (im.split()*2)[:4]), im._new(im.im.color_lut_3d('RGBA', Image.LINEAR, *self.generate_identity_table(4, 17))))
def test_identities_4_channels(self): g = Image.linear_gradient('L') im = Image.merge( 'RGB', [g, g.transpose(Image.ROTATE_90), g.transpose(Image.ROTATE_180)]) # Red channel copied to alpha self.assert_image_equal( Image.merge('RGBA', (im.split() * 2)[:4]), im._new( im.im.color_lut_3d('RGBA', Image.LINEAR, *self.generate_identity_table(4, 17))))
def _prepared_linear_gradient_mask(size, start, end, is_horizontal=True): """Returns prepared linear gradient mask.""" assert end >= 1 mask = invert(Image.linear_gradient('L')) w, h = mask.size box = (0, round(h * start), w, round(h / end)) resized_mask = mask.resize(size, box=box) if is_horizontal: return resized_mask.rotate(90) else: return resized_mask
def test_copy_alpha_channel(self): g = Image.linear_gradient('L') im = Image.merge('RGBA', [ g, g.transpose(Image.ROTATE_90), g.transpose(Image.ROTATE_180), g.transpose(Image.ROTATE_270) ]) self.assert_image_equal( im, im._new( im.im.color_lut_3d('RGBA', Image.LINEAR, *self.generate_identity_table(3, 17))))
def test_overflow(self): g = Image.linear_gradient("L") im = Image.merge( "RGB", [ g, g.transpose(Image.Transpose.ROTATE_90), g.transpose(Image.Transpose.ROTATE_180), ], ) # fmt: off transformed = im._new(im.im.color_lut_3d('RGB', Image.Resampling.BILINEAR, 3, 2, 2, 2, [ -1, -1, -1, 2, -1, -1, -1, 2, -1, 2, 2, -1, -1, -1, 2, 2, -1, 2, -1, 2, 2, 2, 2, 2, ])).load() # fmt: on assert transformed[0, 0] == (0, 0, 255) assert transformed[50, 50] == (0, 0, 255) assert transformed[255, 0] == (0, 255, 255) assert transformed[205, 50] == (0, 255, 255) assert transformed[0, 255] == (255, 0, 0) assert transformed[50, 205] == (255, 0, 0) assert transformed[255, 255] == (255, 255, 0) assert transformed[205, 205] == (255, 255, 0) # fmt: off transformed = im._new(im.im.color_lut_3d('RGB', Image.Resampling.BILINEAR, 3, 2, 2, 2, [ -3, -3, -3, 5, -3, -3, -3, 5, -3, 5, 5, -3, -3, -3, 5, 5, -3, 5, -3, 5, 5, 5, 5, 5, ])).load() # fmt: on assert transformed[0, 0] == (0, 0, 255) assert transformed[50, 50] == (0, 0, 255) assert transformed[255, 0] == (0, 255, 255) assert transformed[205, 50] == (0, 255, 255) assert transformed[0, 255] == (255, 0, 0) assert transformed[50, 205] == (255, 0, 0) assert transformed[255, 255] == (255, 255, 0) assert transformed[205, 205] == (255, 255, 0)
def test_identities(self): g = Image.linear_gradient('L') im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90), g.transpose(Image.ROTATE_180)]) # Fast test with small cubes for size in [2, 3, 5, 7, 11, 16, 17]: self.assert_image_equal(im, im._new( im.im.color_lut_3d('RGB', Image.LINEAR, *self.generate_identity_table(3, size)))) # Not so fast self.assert_image_equal(im, im._new( im.im.color_lut_3d('RGB', Image.LINEAR, *self.generate_identity_table(3, (2, 2, 65)))))
def test_linear_gradient(self): # Arrange target_file = "Tests/images/linear_gradient.png" for mode in ["L", "P"]: # Act im = Image.linear_gradient(mode) # Assert self.assertEqual(im.size, (256, 256)) self.assertEqual(im.mode, mode) self.assertEqual(im.getpixel((0, 0)), 0) self.assertEqual(im.getpixel((255, 255)), 255) target = Image.open(target_file).convert(mode) self.assert_image_equal(im, target)
def test_channels_order(self): g = Image.linear_gradient('L') im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90), g.transpose(Image.ROTATE_180)]) # Reverse channels by splitting and using table self.assert_image_equal( Image.merge('RGB', im.split()[::-1]), im._new(im.im.color_lut_3d('RGB', Image.LINEAR, 3, 2, 2, 2, [ 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, ])))
def randGradLight(img, range): lighter = ImageEnhance.Brightness(img) lighted = lighter.enhance(random.random() * (range[1] - range[0]) + range[0]) lighted2 = lighter.enhance(random.random() * (range[1] - range[0]) + range[0]) #lighted = lighter.enhance(1.6) # 0.4 to 1.6 #lighted2 = lighter.enhance(0.4) gradSize = (math.ceil(math.sqrt(img.size[0]**2 + img.size[1]**2)),) * 2 lightGrad = Image.linear_gradient("L").resize(gradSize) rotLightGrad = lightGrad.rotate(random.randrange(0, 360), expand=False) left, top = (int(0.5*rotLightGrad.width - 0.5*img.width), int(0.5*rotLightGrad.height - 0.5*img.height)) box = (left, top, left + im.width, top + im.height) # left, top, right, bot lighted.paste(lighted2, mask=rotLightGrad.crop(box)) lightGrad.close() rotLightGrad.close() lighted2.close() return lighted
def test_linear_gradient(self): # Arrange target_file = "Tests/images/linear_gradient.png" for mode in ["L", "P"]: # Act im = Image.linear_gradient(mode) # Assert assert im.size == (256, 256) assert im.mode == mode assert im.getpixel((0, 0)) == 0 assert im.getpixel((255, 255)) == 255 with Image.open(target_file) as target: target = target.convert(mode) assert_image_equal(im, target)
def test_overflow(self): g = Image.linear_gradient("L") im = Image.merge( "RGB", [g, g.transpose(Image.ROTATE_90), g.transpose(Image.ROTATE_180)] ) # fmt: off transformed = im._new(im.im.color_lut_3d('RGB', Image.LINEAR, 3, 2, 2, 2, [ -1, -1, -1, 2, -1, -1, -1, 2, -1, 2, 2, -1, -1, -1, 2, 2, -1, 2, -1, 2, 2, 2, 2, 2, ])).load() # fmt: on self.assertEqual(transformed[0, 0], (0, 0, 255)) self.assertEqual(transformed[50, 50], (0, 0, 255)) self.assertEqual(transformed[255, 0], (0, 255, 255)) self.assertEqual(transformed[205, 50], (0, 255, 255)) self.assertEqual(transformed[0, 255], (255, 0, 0)) self.assertEqual(transformed[50, 205], (255, 0, 0)) self.assertEqual(transformed[255, 255], (255, 255, 0)) self.assertEqual(transformed[205, 205], (255, 255, 0)) # fmt: off transformed = im._new(im.im.color_lut_3d('RGB', Image.LINEAR, 3, 2, 2, 2, [ -3, -3, -3, 5, -3, -3, -3, 5, -3, 5, 5, -3, -3, -3, 5, 5, -3, 5, -3, 5, 5, 5, 5, 5, ])).load() # fmt: on self.assertEqual(transformed[0, 0], (0, 0, 255)) self.assertEqual(transformed[50, 50], (0, 0, 255)) self.assertEqual(transformed[255, 0], (0, 255, 255)) self.assertEqual(transformed[205, 50], (0, 255, 255)) self.assertEqual(transformed[0, 255], (255, 0, 0)) self.assertEqual(transformed[50, 205], (255, 0, 0)) self.assertEqual(transformed[255, 255], (255, 255, 0)) self.assertEqual(transformed[205, 205], (255, 255, 0))
def test_channels_order(self): g = Image.linear_gradient("L") im = Image.merge( "RGB", [g, g.transpose(Image.ROTATE_90), g.transpose(Image.ROTATE_180)] ) # Reverse channels by splitting and using table # fmt: off self.assert_image_equal( Image.merge('RGB', im.split()[::-1]), im._new(im.im.color_lut_3d('RGB', Image.LINEAR, 3, 2, 2, 2, [ 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, ])))
def test_identities_4_channels(self): g = Image.linear_gradient("L") im = Image.merge( "RGB", [ g, g.transpose(Image.Transpose.ROTATE_90), g.transpose(Image.Transpose.ROTATE_180), ], ) # Red channel copied to alpha assert_image_equal( Image.merge("RGBA", (im.split() * 2)[:4]), im._new( im.im.color_lut_3d( "RGBA", Image.Resampling.BILINEAR, *self.generate_identity_table(4, 17), )), )
def test_copy_alpha_channel(self): g = Image.linear_gradient("L") im = Image.merge( "RGBA", [ g, g.transpose(Image.Transpose.ROTATE_90), g.transpose(Image.Transpose.ROTATE_180), g.transpose(Image.Transpose.ROTATE_270), ], ) assert_image_equal( im, im._new( im.im.color_lut_3d( "RGBA", Image.Resampling.BILINEAR, *self.generate_identity_table(3, 17), )), )
def test_autocontrast_preserve_gradient(): gradient = Image.linear_gradient("L") # test with a grayscale gradient that extends to 0,255. # Should be a noop. out = ImageOps.autocontrast(gradient, cutoff=0, preserve_tone=True) assert_image_equal(gradient, out) # cutoff the top and bottom # autocontrast should make the first and last histogram entries equal # and, with rounding, should be 10% of the image pixels out = ImageOps.autocontrast(gradient, cutoff=10, preserve_tone=True) hist = out.histogram() assert hist[0] == hist[-1] assert hist[-1] == 256 * round(256 * 0.10) # in rgb img = gradient.convert("RGB") out = ImageOps.autocontrast(img, cutoff=0, preserve_tone=True) assert_image_equal(img, out)
def test_const_diff(): full_grad = Image.linear_gradient("L").convert("RGB") new_size = (4, 32) grad = full_grad.resize(new_size) solid = Image.new("RGB", grad.size, color="blue") src_rgb = Image.blend(grad, solid, 0.5) src_data = color.rgb2lab(np.array(src_rgb)) targ_rgb = Image.blend(grad, solid, 0.2) targ_data = color.rgb2lab(np.array(targ_rgb)) # Matches only value range changes... matcher = ImageMatcher(src_data, targ_data) # Need to normalize the result data. result_data = matcher.adjusted(src_data) print("Source:", src_data) print("Target:", targ_data) print("Result:", result_data) def flatcomp(npa, dim=2): # All columns should have the same value - gradient. dim_vals = npa[:, 0, dim] result = dim_vals.tolist() return result print("Source values:", sorted(set(flatcomp(src_data)))) print("Target values:", sorted(set(flatcomp(targ_data)))) print("Result values:", sorted(set(flatcomp(result_data)))) # Verify the resulting L values are acceptably close to the target. v_diff = result_data[:, 0, 0] - targ_data[:, 0, 0] print("Target data:", targ_data[:, 0, 0]) print("Result data:", result_data[:, 0, 0]) print("Diffs:", v_diff) mean_diff = np.abs(np.mean(v_diff)) assert mean_diff <= 1
def test_overflow(self): g = Image.linear_gradient('L') im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90), g.transpose(Image.ROTATE_180)]) transformed = im._new(im.im.color_lut_3d('RGB', Image.LINEAR, 3, 2, 2, 2, [ -1, -1, -1, 2, -1, -1, -1, 2, -1, 2, 2, -1, -1, -1, 2, 2, -1, 2, -1, 2, 2, 2, 2, 2, ])).load() self.assertEqual(transformed[0, 0], (0, 0, 255)) self.assertEqual(transformed[50, 50], (0, 0, 255)) self.assertEqual(transformed[255, 0], (0, 255, 255)) self.assertEqual(transformed[205, 50], (0, 255, 255)) self.assertEqual(transformed[0, 255], (255, 0, 0)) self.assertEqual(transformed[50, 205], (255, 0, 0)) self.assertEqual(transformed[255, 255], (255, 255, 0)) self.assertEqual(transformed[205, 205], (255, 255, 0)) transformed = im._new(im.im.color_lut_3d('RGB', Image.LINEAR, 3, 2, 2, 2, [ -3, -3, -3, 5, -3, -3, -3, 5, -3, 5, 5, -3, -3, -3, 5, 5, -3, 5, -3, 5, 5, 5, 5, 5, ])).load() self.assertEqual(transformed[0, 0], (0, 0, 255)) self.assertEqual(transformed[50, 50], (0, 0, 255)) self.assertEqual(transformed[255, 0], (0, 255, 255)) self.assertEqual(transformed[205, 50], (0, 255, 255)) self.assertEqual(transformed[0, 255], (255, 0, 0)) self.assertEqual(transformed[50, 205], (255, 0, 0)) self.assertEqual(transformed[255, 255], (255, 255, 0)) self.assertEqual(transformed[205, 205], (255, 255, 0))
def test_numpy_formats(self): g = Image.linear_gradient('L') im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90), g.transpose(Image.ROTATE_180)]) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut.table = numpy.array(lut.table, dtype=numpy.float32)[:-1] with self.assertRaisesRegex(ValueError, "should have table_channels"): im.filter(lut) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut.table = (numpy.array(lut.table, dtype=numpy.float32) .reshape((7 * 9 * 11), 3)) with self.assertRaisesRegex(ValueError, "should have table_channels"): im.filter(lut) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut.table = numpy.array(lut.table, dtype=numpy.float16) self.assert_image_equal(im, im.filter(lut)) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut.table = numpy.array(lut.table, dtype=numpy.float32) self.assert_image_equal(im, im.filter(lut)) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut.table = numpy.array(lut.table, dtype=numpy.float64) self.assert_image_equal(im, im.filter(lut)) lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b)) lut.table = numpy.array(lut.table, dtype=numpy.int32) im.filter(lut) lut.table = numpy.array(lut.table, dtype=numpy.int8) im.filter(lut)