diff --git a/ChangeLog b/ChangeLog index 52b82744..c363c142 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,7 @@ - dzsave removes tile metadata by default, thanks Benjamin - added vips_image_new_from_memory_copy() - added vips_arrayjoin() +- Python x.bandjoin(y) is now x.ibandjoin(y), sorry 7/5/15 started 8.1.1 - oop, vips-8.0 wrapper script should be vips-8.1, thanks Danilo diff --git a/TODO b/TODO index a033d7d3..4dc35f5f 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,10 @@ +- add tests for vips_arrayjoin() + + and valgrind it too + + could crop before we pad, perhaps? we could nest two embeds, that might be + simpler + - get some brightly coloured spots with nohalo / vsqbs on wobble.ws ... very odd, the interpolation shouldn't change between bands diff --git a/doc/function-list.xml b/doc/function-list.xml index 5bf42e9f..7fa25024 100644 --- a/doc/function-list.xml +++ b/doc/function-list.xml @@ -318,6 +318,11 @@ join a pair of images vips_join() + + arrayjoin + join an array of images + vips_arrayjoin() + extract_area extract an area from an image @@ -335,7 +340,7 @@ bandjoin_const - appendd a set of constants to an image + append a constant band to an image vips_bandjoin_const(), vips_bandjoin_const1() @@ -777,9 +782,9 @@ vips_shrink() - quadratic - resample an image with a quadratic transform - vips_quadratic() + mapim + resample an image with an arbitrary warp + vips_mapim() affine diff --git a/doc/using-python.xml b/doc/using-python.xml index eb605a78..d4e2ebd4 100644 --- a/doc/using-python.xml +++ b/doc/using-python.xml @@ -461,21 +461,41 @@ result_image = condition_image.ifthenelse([0, 255, 0], [255, 0, 0]) two or more images up bandwise. You can write: -rgba = rgb.bandjoin(255) +rgba = rgb.ibandjoin(255) to add a constant 255 band to an image, perhaps to add an alpha channel. Of course you can also write: -result_image = image1.bandjoin(image2) -result_image = image1.bandjoin([image2, image3]) +result_image = image1.ibandjoin(image2) +result_image = image1.ibandjoin([image2, image3]) result_image = Vips.Image.bandjoin([image1, image2, image3]) -result_image = image1.bandjoin([image2, 255]) +result_image = image1.ibandjoin([image2, 255]) and so on. + + + There's one annoying wrinkle in .bandjoin(). The vips + operation vips_bandjoin() takes an array of images to join, + so you can't use it as an instance member, it appears in the API as + + +result_image = Vips.Image.bandjoin([image1, image2, image3]) + + + For convenience, the wrapper has an extra instance function called + .ibandjoin() which puts the self at the head + of the image array. This means the previous line is the same as: + + +result_image = image1.ibandjoin([image2, image3]) + + + + diff --git a/python/Vips.py b/python/Vips.py index b78d2d70..7648a2f0 100644 --- a/python/Vips.py +++ b/python/Vips.py @@ -906,7 +906,9 @@ class Image(Vips.Image): """Split an n-band image into n separate images.""" return [x for x in self] - def bandjoin(self, other): + # bandjoin as an instance method ... it needs a different name, + # unfortunately + def ibandjoin(self, other): """Append a set of images or constants bandwise.""" if not isinstance(other, list): other = [other] diff --git a/test/test_conversion.py b/test/test_conversion.py index bcaa7cca..2d90c054 100755 --- a/test/test_conversion.py +++ b/test/test_conversion.py @@ -173,7 +173,7 @@ class TestConversion(unittest.TestCase): def test_bandjoin(self): def bandjoin(x, y): if isinstance(x, Vips.Image) and isinstance(y, Vips.Image): - return x.bandjoin(y) + return x.ibandjoin(y) else: return x + y @@ -382,7 +382,7 @@ class TestConversion(unittest.TestCase): mx = 255 alpha = mx / 2.0 nalpha = mx - alpha - test = self.colour.bandjoin(alpha).cast(fmt) + test = self.colour.ibandjoin(alpha).cast(fmt) pixel = test(30, 30) predict = [int(x) * alpha / mx for x in pixel[:-1]] @@ -413,7 +413,7 @@ class TestConversion(unittest.TestCase): mx = 255 alpha = mx / 2.0 nalpha = mx - alpha - test = self.colour.bandjoin(alpha).cast(fmt) + test = self.colour.ibandjoin(alpha).cast(fmt) pixel = test(30, 30) predict = [int(x) * alpha / mx for x in pixel[:-1]] + [alpha] @@ -433,7 +433,7 @@ class TestConversion(unittest.TestCase): mx = 255 alpha = mx / 2.0 nalpha = mx - alpha - test = self.colour.bandjoin(alpha).cast(fmt) + test = self.colour.ibandjoin(alpha).cast(fmt) pixel = test(30, 30) predict = [int(x) / (alpha / mx) for x in pixel[:-1]] + [alpha] @@ -627,6 +627,19 @@ class TestConversion(unittest.TestCase): a = r(r.width - 5, 5) self.assertAlmostEqualObjects(a, [100, 100, 100]) + def test_arrayjoin(self): + max_width = 0 + max_height = 0 + for image in self.all_images: + if image.width > max_width: + max_width = image.width + if image.height > max_height: + max_height = image.height + + im = Vips.Image.arrayjoin(self.all_images) + self.assertEqual(im.width, max_width * len(self.all_images)) + self.assertEqual(im.height, max_height) + def test_msb(self): for fmt in unsigned_formats: mx = max_value[fmt] diff --git a/test/test_foreign.py b/test/test_foreign.py index 9d0444e2..41fe8645 100755 --- a/test/test_foreign.py +++ b/test/test_foreign.py @@ -48,7 +48,7 @@ class TestForeign(unittest.TestCase): self.colour = Vips.Image.jpegload(self.jpeg_file) self.mono = self.colour.extract_band(1) self.rad = self.colour.float2rad() - self.cmyk = self.colour.bandjoin(self.mono) + self.cmyk = self.colour.ibandjoin(self.mono) self.cmyk = self.cmyk.copy(interpretation = Vips.Interpretation.CMYK) im = Vips.Image.new_from_file(self.gif_file)