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)