Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 529eb3d

Browse files
authored
Merge pull request #11735 from anntzer/aggbufferrgba
Change {FigureCanvasAgg,RendererAgg}.buffer_rgba to return a memoryview.
2 parents 6c3c28e + 5c16eca commit 529eb3d

File tree

6 files changed

+20
-73
lines changed

6 files changed

+20
-73
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
`FigureCanvasAgg.buffer_rgba` and `RendererAgg.buffer_rgba` now return a memoryview
2+
```````````````````````````````````````````````````````````````````````````````````
3+
4+
The ``buffer_rgba`` method now allows direct access to the renderer's
5+
underlying buffer (as a ``(m, n, 4)``-shape memoryview) rather than copying the
6+
data to a new bytestring. This is consistent with the behavior on Py2, where a
7+
buffer object was returned.

examples/misc/agg_buffer_to_array.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
fig.canvas.draw()
1616

1717
# grab the pixel buffer and dump it into a numpy array
18-
X = np.array(fig.canvas.renderer._renderer)
18+
X = np.array(fig.canvas.renderer.buffer_rgba())
1919

2020
# now display the array X as an Axes in a new figure
2121
fig2 = plt.figure()

lib/matplotlib/backends/backend_agg.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -256,14 +256,14 @@ def points_to_pixels(self, points):
256256
# docstring inherited
257257
return points * self.dpi / 72
258258

259-
def tostring_rgb(self):
260-
return self._renderer.tostring_rgb()
259+
def buffer_rgba(self):
260+
return memoryview(self._renderer)
261261

262262
def tostring_argb(self):
263-
return self._renderer.tostring_argb()
263+
return np.asarray(self._renderer).take([3, 0, 1, 2], axis=2).tobytes()
264264

265-
def buffer_rgba(self):
266-
return self._renderer.buffer_rgba()
265+
def tostring_rgb(self):
266+
return np.asarray(self._renderer).take([0, 1, 2], axis=2).tobytes()
267267

268268
def clear(self):
269269
self._renderer.clear()
@@ -409,40 +409,39 @@ def get_renderer(self, cleared=False):
409409
return self.renderer
410410

411411
def tostring_rgb(self):
412-
'''Get the image as an RGB byte string.
412+
"""Get the image as an RGB byte string.
413413
414414
`draw` must be called at least once before this function will work and
415415
to update the renderer for any subsequent changes to the Figure.
416416
417417
Returns
418418
-------
419419
bytes
420-
'''
420+
"""
421421
return self.renderer.tostring_rgb()
422422

423423
def tostring_argb(self):
424-
'''Get the image as an ARGB byte string
424+
"""Get the image as an ARGB byte string.
425425
426426
`draw` must be called at least once before this function will work and
427427
to update the renderer for any subsequent changes to the Figure.
428428
429429
Returns
430430
-------
431431
bytes
432-
433-
'''
432+
"""
434433
return self.renderer.tostring_argb()
435434

436435
def buffer_rgba(self):
437-
'''Get the image as an RGBA byte string.
436+
"""Get the image as a memoryview to the renderer's buffer.
438437
439438
`draw` must be called at least once before this function will work and
440439
to update the renderer for any subsequent changes to the Figure.
441440
442441
Returns
443442
-------
444-
bytes
445-
'''
443+
memoryview
444+
"""
446445
return self.renderer.buffer_rgba()
447446

448447
def print_raw(self, filename_or_obj, *args, **kwargs):

src/_backend_agg.cpp

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -156,29 +156,6 @@ bool RendererAgg::render_clippath(py::PathIterator &clippath,
156156
return has_clippath;
157157
}
158158

159-
void RendererAgg::tostring_rgb(uint8_t *buf)
160-
{
161-
// "Return the rendered buffer as an RGB string"
162-
163-
int row_len = width * 3;
164-
165-
agg::rendering_buffer renderingBufferTmp;
166-
renderingBufferTmp.attach(buf, width, height, row_len);
167-
168-
agg::color_conv(&renderingBufferTmp, &renderingBuffer, agg::color_conv_rgba32_to_rgb24());
169-
}
170-
171-
void RendererAgg::tostring_argb(uint8_t *buf)
172-
{
173-
//"Return the rendered buffer as an RGB string";
174-
175-
int row_len = width * 4;
176-
177-
agg::rendering_buffer renderingBufferTmp;
178-
renderingBufferTmp.attach(buf, width, height, row_len);
179-
agg::color_conv(&renderingBufferTmp, &renderingBuffer, agg::color_conv_rgba32_to_argb32());
180-
}
181-
182159
agg::rect_i RendererAgg::get_content_extents()
183160
{
184161
agg::rect_i r(width, height, 0, 0);

src/_backend_agg.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,6 @@ class RendererAgg
203203
ColorArray &colors,
204204
agg::trans_affine &trans);
205205

206-
void tostring_rgb(uint8_t *buf);
207-
void tostring_argb(uint8_t *buf);
208206
agg::rect_i get_content_extents();
209207
void clear();
210208

src/_backend_agg_wrapper.cpp

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -525,38 +525,6 @@ PyRendererAgg_draw_gouraud_triangles(PyRendererAgg *self, PyObject *args, PyObje
525525
Py_RETURN_NONE;
526526
}
527527

528-
static PyObject *PyRendererAgg_tostring_rgb(PyRendererAgg *self, PyObject *args, PyObject *kwds)
529-
{
530-
PyObject *buffobj = NULL;
531-
532-
buffobj = PyBytes_FromStringAndSize(NULL, self->x->get_width() * self->x->get_height() * 3);
533-
if (buffobj == NULL) {
534-
return NULL;
535-
}
536-
537-
CALL_CPP_CLEANUP("tostring_rgb",
538-
(self->x->tostring_rgb((uint8_t *)PyBytes_AS_STRING(buffobj))),
539-
Py_DECREF(buffobj));
540-
541-
return buffobj;
542-
}
543-
544-
static PyObject *PyRendererAgg_tostring_argb(PyRendererAgg *self, PyObject *args, PyObject *kwds)
545-
{
546-
PyObject *buffobj = NULL;
547-
548-
buffobj = PyBytes_FromStringAndSize(NULL, self->x->get_width() * self->x->get_height() * 4);
549-
if (buffobj == NULL) {
550-
return NULL;
551-
}
552-
553-
CALL_CPP_CLEANUP("tostring_argb",
554-
(self->x->tostring_argb((uint8_t *)PyBytes_AS_STRING(buffobj))),
555-
Py_DECREF(buffobj));
556-
557-
return buffobj;
558-
}
559-
560528
static PyObject *
561529
PyRendererAgg_get_content_extents(PyRendererAgg *self, PyObject *args, PyObject *kwds)
562530
{
@@ -664,8 +632,6 @@ static PyTypeObject *PyRendererAgg_init_type(PyObject *m, PyTypeObject *type)
664632
{"draw_gouraud_triangle", (PyCFunction)PyRendererAgg_draw_gouraud_triangle, METH_VARARGS, NULL},
665633
{"draw_gouraud_triangles", (PyCFunction)PyRendererAgg_draw_gouraud_triangles, METH_VARARGS, NULL},
666634

667-
{"tostring_rgb", (PyCFunction)PyRendererAgg_tostring_rgb, METH_NOARGS, NULL},
668-
{"tostring_argb", (PyCFunction)PyRendererAgg_tostring_argb, METH_NOARGS, NULL},
669635
{"get_content_extents", (PyCFunction)PyRendererAgg_get_content_extents, METH_NOARGS, NULL},
670636
{"buffer_rgba", (PyCFunction)PyRendererAgg_buffer_rgba, METH_NOARGS, NULL},
671637
{"clear", (PyCFunction)PyRendererAgg_clear, METH_NOARGS, NULL},

0 commit comments

Comments
 (0)