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); } }