Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 529eb3d

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

File tree

Expand file treeCollapse file tree

6 files changed

+20
-73
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+20
-73
lines changed
+7Lines 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

Copy file name to clipboardExpand all lines: examples/misc/agg_buffer_to_array.py
+1-1Lines 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

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/backend_agg.py
+12-13Lines 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

Copy file name to clipboardExpand all lines: src/_backend_agg.cpp
-23Lines 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

Copy file name to clipboardExpand all lines: src/_backend_agg.h
-2Lines 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

Copy file name to clipboardExpand all lines: src/_backend_agg_wrapper.cpp
-34Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.