diff --git a/lib/matplotlib/axes.py b/lib/matplotlib/axes.py
index 354f472fcc37..cd02555f8377 100644
--- a/lib/matplotlib/axes.py
+++ b/lib/matplotlib/axes.py
@@ -2054,7 +2054,7 @@ def draw(self, renderer=None, inframe=False):
zorder_images.sort(key=lambda x: x[0])
mag = renderer.get_image_magnification()
- ims = [(im.make_image(mag), 0, 0) for z, im in zorder_images]
+ ims = [(im.make_image(mag), 0, 0, im.get_alpha()) for z, im in zorder_images]
l, b, r, t = self.bbox.extents
width = mag * ((round(r) + 0.5) - (round(l) - 0.5))
diff --git a/lib/matplotlib/backends/backend_cairo.py b/lib/matplotlib/backends/backend_cairo.py
index a5e50e9cfb55..aacb9c1ee760 100644
--- a/lib/matplotlib/backends/backend_cairo.py
+++ b/lib/matplotlib/backends/backend_cairo.py
@@ -163,8 +163,11 @@ def draw_image(self, gc, x, y, im):
buf, cairo.FORMAT_ARGB32, cols, rows, cols*4)
ctx = gc.ctx
y = self.height - y - rows
+
+ ctx.save()
ctx.set_source_surface (surface, x, y)
ctx.paint()
+ ctx.restore()
im.flipud_out()
diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py
index 51716759645e..38c1e2483739 100644
--- a/lib/matplotlib/figure.py
+++ b/lib/matplotlib/figure.py
@@ -990,7 +990,7 @@ def draw(self, renderer):
# make a composite image blending alpha
# list of (_image.Image, ox, oy)
mag = renderer.get_image_magnification()
- ims = [(im.make_image(mag), im.ox, im.oy)
+ ims = [(im.make_image(mag), im.ox, im.oy, im.get_alpha())
for im in self.images]
im = _image.from_images(self.bbox.height * mag,
diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.pdf b/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.pdf
new file mode 100644
index 000000000000..65c23cdbfb45
Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.pdf differ
diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.png b/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.png
new file mode 100644
index 000000000000..48acef4223e2
Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.png differ
diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.svg b/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.svg
new file mode 100644
index 000000000000..b46da90d064b
--- /dev/null
+++ b/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.svg
@@ -0,0 +1,212 @@
+
+
+
+
diff --git a/lib/matplotlib/tests/test_image.py b/lib/matplotlib/tests/test_image.py
index 6132bc16e87c..b0345135e834 100644
--- a/lib/matplotlib/tests/test_image.py
+++ b/lib/matplotlib/tests/test_image.py
@@ -235,6 +235,32 @@ def test_image_composite_background():
ax.set_axis_bgcolor((1, 0, 0, 0.5))
ax.set_xlim([0, 12])
+@image_comparison(baseline_images=['image_composite_alpha'], remove_text=True)
+def test_image_composite_alpha():
+ """
+ Tests that the alpha value is recognized and correctly applied in the
+ process of compositing images together.
+ """
+ fig = plt.figure()
+ ax = fig.add_subplot(111)
+ arr = np.zeros((11, 21, 4))
+ arr[:, :, 0] = 1
+ arr[:, :, 3] = np.concatenate((np.arange(0, 1.1, 0.1), np.arange(0, 1, 0.1)[::-1]))
+ arr2 = np.zeros((21, 11, 4))
+ arr2[:, :, 0] = 1
+ arr2[:, :, 1] = 1
+ arr2[:, :, 3] = np.concatenate((np.arange(0, 1.1, 0.1), np.arange(0, 1, 0.1)[::-1]))[:, np.newaxis]
+ ax.imshow(arr, extent=[1, 2, 5, 0], alpha=0.3)
+ ax.imshow(arr, extent=[2, 3, 5, 0], alpha=0.6)
+ ax.imshow(arr, extent=[3, 4, 5, 0])
+ ax.imshow(arr2, extent=[0, 5, 1, 2])
+ ax.imshow(arr2, extent=[0, 5, 2, 3], alpha=0.6)
+ ax.imshow(arr2, extent=[0, 5, 3, 4], alpha=0.3)
+ ax.set_axis_bgcolor((0, 0.5, 0, 1))
+ ax.set_xlim([0, 5])
+ ax.set_ylim([5, 0])
+
+
if __name__=='__main__':
import nose
nose.runmodule(argv=['-s','--with-doctest'], exit=False)
diff --git a/src/_image.cpp b/src/_image.cpp
index 13377eeed3e7..9e77ea9613e9 100644
--- a/src/_image.cpp
+++ b/src/_image.cpp
@@ -796,6 +796,8 @@ _image_module::from_images(const Py::Tuple& args)
Py::Tuple tup;
size_t ox(0), oy(0), thisx(0), thisy(0);
+ float alpha;
+ bool apply_alpha;
//copy image 0 output buffer into return images output buffer
Image* imo = new Image;
@@ -823,6 +825,16 @@ _image_module::from_images(const Py::Tuple& args)
Image* thisim = static_cast(tup[0].ptr());
ox = (long)Py::Int(tup[1]);
oy = (long)Py::Int(tup[2]);
+ if (tup.size() <= 3 || tup[3].ptr() == Py_None)
+ {
+ apply_alpha = false;
+ }
+ else
+ {
+ apply_alpha = true;
+ alpha = Py::Float(tup[3]);
+ }
+
bool isflip = (thisim->rbufOut->stride()) < 0;
//std::cout << "from images " << isflip << "; stride=" << thisim->rbufOut->stride() << std::endl;
size_t ind = 0;
@@ -851,7 +863,14 @@ _image_module::from_images(const Py::Tuple& args)
p.r = *(thisim->bufferOut + ind++);
p.g = *(thisim->bufferOut + ind++);
p.b = *(thisim->bufferOut + ind++);
- p.a = *(thisim->bufferOut + ind++);
+ if (apply_alpha)
+ {
+ p.a = (pixfmt::value_type) *(thisim->bufferOut + ind++) * alpha;
+ }
+ else
+ {
+ p.a = *(thisim->bufferOut + ind++);
+ }
pixf.blend_pixel(thisx, thisy, p, 255);
}
}