bandjoin is just an instance function

we had both a class member bandjoin, and an instance member

Vips.Image.bandjoin([i1, i2, i3..])
i1.ibandjoin([i2, i3..])

this was confusing and annoying ... get rid of the class one and just
use bandjoin everywhere, so this is now the way to do it:

i1.bandjoin([i2, i3..])
This commit is contained in:
John Cupitt 2016-01-04 14:18:10 +00:00
parent e6cbdbb516
commit e81900b187
7 changed files with 26 additions and 49 deletions

View File

@ -1,5 +1,6 @@
1/1/16 started 8.2.1 1/1/16 started 8.2.1
- add a compat stub, thanks Benjamin - add a compat stub, thanks Benjamin
- bandjoin is now just an instance function
7/10/15 started 8.2.0 7/10/15 started 8.2.0
- added im_bufmagick2vips(), a vips7 wrapper for magick load from buffer - added im_bufmagick2vips(), a vips7 wrapper for magick load from buffer

View File

@ -25,7 +25,6 @@ TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE)
SETUP_FILES = \ SETUP_FILES = \
$(content_files) \ $(content_files) \
$(expand_content_files) \
$(DOC_MAIN_SGML_FILE) \ $(DOC_MAIN_SGML_FILE) \
$(DOC_MODULE)-sections.txt \ $(DOC_MODULE)-sections.txt \
$(DOC_MODULE)-overrides.txt $(DOC_MODULE)-overrides.txt
@ -87,7 +86,7 @@ GTK_DOC_V_SETUP_0=@echo " DOC Preparing build";
setup-build.stamp: setup-build.stamp:
-$(GTK_DOC_V_SETUP)if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ -$(GTK_DOC_V_SETUP)if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \
files=`echo $(SETUP_FILES) $(DOC_MODULE).types`; \ files=`echo $(SETUP_FILES) $(expand_content_files) $(DOC_MODULE).types`; \
if test "x$$files" != "x" ; then \ if test "x$$files" != "x" ; then \
for file in $$files ; do \ for file in $$files ; do \
destdir=`dirname $(abs_builddir)/$$file`; \ destdir=`dirname $(abs_builddir)/$$file`; \
@ -119,7 +118,7 @@ scan-build.stamp: setup-build.stamp $(HFILE_GLOB) $(CFILE_GLOB)
$(GTK_DOC_V_INTROSPECT)if grep -l '^..*$$' $(DOC_MODULE).types > /dev/null 2>&1 ; then \ $(GTK_DOC_V_INTROSPECT)if grep -l '^..*$$' $(DOC_MODULE).types > /dev/null 2>&1 ; then \
scanobj_options=""; \ scanobj_options=""; \
gtkdoc-scangobj 2>&1 --help | grep >/dev/null "\-\-verbose"; \ gtkdoc-scangobj 2>&1 --help | grep >/dev/null "\-\-verbose"; \
if test "$$?" = "0"; then \ if test "$(?)" = "0"; then \
if test "x$(V)" = "x1"; then \ if test "x$(V)" = "x1"; then \
scanobj_options="--verbose"; \ scanobj_options="--verbose"; \
fi; \ fi; \
@ -163,17 +162,17 @@ GTK_DOC_V_XREF=$(GTK_DOC_V_XREF_$(V))
GTK_DOC_V_XREF_=$(GTK_DOC_V_XREF_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_XREF_=$(GTK_DOC_V_XREF_$(AM_DEFAULT_VERBOSITY))
GTK_DOC_V_XREF_0=@echo " DOC Fixing cross-references"; GTK_DOC_V_XREF_0=@echo " DOC Fixing cross-references";
html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files) html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files)
$(GTK_DOC_V_HTML)rm -rf html && mkdir html && \ $(GTK_DOC_V_HTML)rm -rf html && mkdir html && \
mkhtml_options=""; \ mkhtml_options=""; \
gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-verbose"; \ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-verbose"; \
if test "$$?" = "0"; then \ if test "$(?)" = "0"; then \
if test "x$(V)" = "x1"; then \ if test "x$(V)" = "x1"; then \
mkhtml_options="$$mkhtml_options --verbose"; \ mkhtml_options="$$mkhtml_options --verbose"; \
fi; \ fi; \
fi; \ fi; \
gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \
if test "$$?" = "0"; then \ if test "$(?)" = "0"; then \
mkhtml_options="$$mkhtml_options --path=\"$(abs_srcdir)\""; \ mkhtml_options="$$mkhtml_options --path=\"$(abs_srcdir)\""; \
fi; \ fi; \
cd html && gtkdoc-mkhtml $$mkhtml_options $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) cd html && gtkdoc-mkhtml $$mkhtml_options $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE)
@ -195,11 +194,11 @@ GTK_DOC_V_PDF=$(GTK_DOC_V_PDF_$(V))
GTK_DOC_V_PDF_=$(GTK_DOC_V_PDF_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_PDF_=$(GTK_DOC_V_PDF_$(AM_DEFAULT_VERBOSITY))
GTK_DOC_V_PDF_0=@echo " DOC Building PDF"; GTK_DOC_V_PDF_0=@echo " DOC Building PDF";
pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files) pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files)
$(GTK_DOC_V_PDF)rm -f $(DOC_MODULE).pdf && \ $(GTK_DOC_V_PDF)rm -f $(DOC_MODULE).pdf && \
mkpdf_options=""; \ mkpdf_options=""; \
gtkdoc-mkpdf 2>&1 --help | grep >/dev/null "\-\-verbose"; \ gtkdoc-mkpdf 2>&1 --help | grep >/dev/null "\-\-verbose"; \
if test "$$?" = "0"; then \ if test "$(?)" = "0"; then \
if test "x$(V)" = "x1"; then \ if test "x$(V)" = "x1"; then \
mkpdf_options="$$mkpdf_options --verbose"; \ mkpdf_options="$$mkpdf_options --verbose"; \
fi; \ fi; \
@ -224,15 +223,12 @@ clean-local:
@if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-types" ; then \ @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-types" ; then \
rm -f $(DOC_MODULE).types; \ rm -f $(DOC_MODULE).types; \
fi fi
@if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-sections" ; then \
rm -f $(DOC_MODULE)-sections.txt; \
fi
distclean-local: distclean-local:
@rm -rf xml html $(REPORT_FILES) $(DOC_MODULE).pdf \ @rm -rf xml html $(REPORT_FILES) $(DOC_MODULE).pdf \
$(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt
@if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ @if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \
rm -f $(SETUP_FILES) $(DOC_MODULE).types; \ rm -f $(SETUP_FILES) $(expand_content_files) $(DOC_MODULE).types; \
fi fi
maintainer-clean-local: maintainer-clean-local:

View File

@ -9,7 +9,7 @@
<bookinfo> <bookinfo>
<title>VIPS Reference Manual</title> <title>VIPS Reference Manual</title>
<releaseinfo> <releaseinfo>
For VIPS 8.2.0. For VIPS 8.2.1.
The latest version of this documentation can be found on the The latest version of this documentation can be found on the
<ulink role="online-location" <ulink role="online-location"
url="http://www.vips.ecs.soton.ac.uk/index.php?title=Documentation">VIPS website</ulink>. url="http://www.vips.ecs.soton.ac.uk/index.php?title=Documentation">VIPS website</ulink>.

View File

@ -461,41 +461,21 @@ result_image = condition_image.ifthenelse([0, 255, 0], [255, 0, 0])
two or more images up bandwise. You can write: two or more images up bandwise. You can write:
<programlisting language="Python"> <programlisting language="Python">
rgba = rgb.ibandjoin(255) rgba = rgb.bandjoin(255)
</programlisting> </programlisting>
to add a constant 255 band to an image, perhaps to add an alpha to add a constant 255 band to an image, perhaps to add an alpha
channel. Of course you can also write: channel. Of course you can also write:
<programlisting language="Python"> <programlisting language="Python">
result_image = image1.ibandjoin(image2) result_image = image1.bandjoin(image2)
result_image = image1.ibandjoin([image2, image3]) result_image = image1.bandjoin([image2, image3])
result_image = Vips.Image.bandjoin([image1, image2, image3]) result_image = image1.bandjoin([image2, 255])
result_image = image1.ibandjoin([image2, 255])
</programlisting> </programlisting>
and so on. and so on.
</para> </para>
<para>
There's one annoying wrinkle in <code>.bandjoin()</code>. The vips
operation <code>vips_bandjoin()</code> takes an array of images to join,
so you can't use it as an instance member, it appears in the API as
<programlisting language="Python">
result_image = Vips.Image.bandjoin([image1, image2, image3])
</programlisting>
For convenience, the wrapper has an extra instance function called
<code>.ibandjoin()</code> which puts the <code>self</code> at the head
of the image array. This means the previous line is the same as:
<programlisting language="Python">
result_image = image1.ibandjoin([image2, image3])
</programlisting>
</para>
</refsect3> </refsect3>
<refsect3 id="python-exceptions"> <refsect3 id="python-exceptions">

View File

@ -906,9 +906,7 @@ class Image(Vips.Image):
"""Split an n-band image into n separate images.""" """Split an n-band image into n separate images."""
return [x for x in self] return [x for x in self]
# bandjoin as an instance method ... it needs a different name, def bandjoin(self, other):
# unfortunately
def ibandjoin(self, other):
"""Append a set of images or constants bandwise.""" """Append a set of images or constants bandwise."""
if not isinstance(other, list): if not isinstance(other, list):
other = [other] other = [other]
@ -921,7 +919,7 @@ class Image(Vips.Image):
if non_number == None: if non_number == None:
return self.bandjoin_const(other) return self.bandjoin_const(other)
else: else:
return Vips.Image.bandjoin([self] + other) return _call_base("bandjoin", [[self] + other], {})
def maxpos(self): def maxpos(self):
"""Return the coordinates of the image maximum.""" """Return the coordinates of the image maximum."""
@ -1048,10 +1046,12 @@ class Image(Vips.Image):
# use find_class_methods.py to generate this list # use find_class_methods.py to generate this list
# don't include "bandjoin", this needs to be wrapped by hand, see
# above
class_methods = [ class_methods = [
"system", "system",
"sum", "sum",
"bandjoin",
"arrayjoin", "arrayjoin",
"bandrank", "bandrank",
"black", "black",

View File

@ -173,18 +173,18 @@ class TestConversion(unittest.TestCase):
def test_bandjoin(self): def test_bandjoin(self):
def bandjoin(x, y): def bandjoin(x, y):
if isinstance(x, Vips.Image) and isinstance(y, Vips.Image): if isinstance(x, Vips.Image) and isinstance(y, Vips.Image):
return x.ibandjoin(y) return x.bandjoin(y)
else: else:
return x + y return x + y
self.run_binary(self.all_images, bandjoin) self.run_binary(self.all_images, bandjoin)
def test_bandjoin_const(self): def test_bandjoin_const(self):
x = self.colour.ibandjoin(1) x = self.colour.bandjoin(1)
self.assertEqual(x.bands, 4) self.assertEqual(x.bands, 4)
self.assertEqual(x[3].avg(), 1) self.assertEqual(x[3].avg(), 1)
x = self.colour.ibandjoin([1,2]) x = self.colour.bandjoin([1,2])
self.assertEqual(x.bands, 5) self.assertEqual(x.bands, 5)
self.assertEqual(x[3].avg(), 1) self.assertEqual(x[3].avg(), 1)
self.assertEqual(x[4].avg(), 2) self.assertEqual(x[4].avg(), 2)
@ -382,7 +382,7 @@ class TestConversion(unittest.TestCase):
mx = 255 mx = 255
alpha = mx / 2.0 alpha = mx / 2.0
nalpha = mx - alpha nalpha = mx - alpha
test = self.colour.ibandjoin(alpha).cast(fmt) test = self.colour.bandjoin(alpha).cast(fmt)
pixel = test(30, 30) pixel = test(30, 30)
predict = [int(x) * alpha / mx for x in pixel[:-1]] predict = [int(x) * alpha / mx for x in pixel[:-1]]
@ -413,7 +413,7 @@ class TestConversion(unittest.TestCase):
mx = 255 mx = 255
alpha = mx / 2.0 alpha = mx / 2.0
nalpha = mx - alpha nalpha = mx - alpha
test = self.colour.ibandjoin(alpha).cast(fmt) test = self.colour.bandjoin(alpha).cast(fmt)
pixel = test(30, 30) pixel = test(30, 30)
predict = [int(x) * alpha / mx for x in pixel[:-1]] + [alpha] predict = [int(x) * alpha / mx for x in pixel[:-1]] + [alpha]
@ -433,7 +433,7 @@ class TestConversion(unittest.TestCase):
mx = 255 mx = 255
alpha = mx / 2.0 alpha = mx / 2.0
nalpha = mx - alpha nalpha = mx - alpha
test = self.colour.ibandjoin(alpha).cast(fmt) test = self.colour.bandjoin(alpha).cast(fmt)
pixel = test(30, 30) pixel = test(30, 30)
predict = [int(x) / (alpha / mx) for x in pixel[:-1]] + [alpha] predict = [int(x) / (alpha / mx) for x in pixel[:-1]] + [alpha]

View File

@ -48,7 +48,7 @@ class TestForeign(unittest.TestCase):
self.colour = Vips.Image.jpegload(self.jpeg_file) self.colour = Vips.Image.jpegload(self.jpeg_file)
self.mono = self.colour.extract_band(1) self.mono = self.colour.extract_band(1)
self.rad = self.colour.float2rad() self.rad = self.colour.float2rad()
self.cmyk = self.colour.ibandjoin(self.mono) self.cmyk = self.colour.bandjoin(self.mono)
self.cmyk = self.cmyk.copy(interpretation = Vips.Interpretation.CMYK) self.cmyk = self.cmyk.copy(interpretation = Vips.Interpretation.CMYK)
im = Vips.Image.new_from_file(self.gif_file) im = Vips.Image.new_from_file(self.gif_file)