8000 Cleanup to image.py. · matplotlib/matplotlib@9e42692 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9e42692

Browse files
committed
Cleanup to image.py.
PIL.Image.Image.tobytes has existed since Pillow 2.0, which was released in March 2013, and is also the first version to support Python 3. One may want to add a check for the Pillow version, although it is superfluous on Py3. (While updating the docs on the required version of Pillow, also remove mencoder from the dependencies doc, as its support is deprecated anyways.)
1 parent 4c33d97 commit 9e42692

File tree

2 files changed

+64
-99
lines changed

2 files changed

+64
-99
lines changed

INSTALL.rst

Lines changed: 8 additions & 9 deletions
< 8000 td data-grid-cell-id="diff-ce342037df7e6de102c3157b708a389b128142aae879421094c71d9f97f5084c-217-213-0" data-selected="false" role="gridcell" style="background-color:var(--diffBlob-additionNum-bgColor, var(--diffBlob-addition-bgColor-num));text-align:center" tabindex="-1" valign="top" class="focusable-grid-cell diff-line-number position-relative left-side">
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,14 @@ optional Matplotlib backends and the capabilities they provide.
206206
For better support of animation output format and image file formats, LaTeX,
207207
etc., you can install the following:
208208

209-
* `ffmpeg <https://www.ffmpeg.org/>`__/`avconv
210-
<https://libav.org/avconv.html>`__ or `mencoder
211-
<https://mplayerhq.hu/design7/news.html>`__ (for saving movies);
212-
* `ImageMagick <https://www.imagemagick.org/script/index.php>`__ (for saving
213-
animated gifs);
214-
* `Pillow <https://python-pillow.org/>`__ (for a larger selection of image
215-
file formats: JPEG, BMP, and TIFF image files);
216-
* `LaTeX <https://miktex.org/>`_ and `GhostScript <https://ghostscript.com/download/>`_
217-
(for rendering text with LaTeX);
209+
* `ffmpeg <https://www.ffmpeg.org/>`_/`avconv
210+
<https://libav.org/avconv.html>`_: for saving movies;
211+
* `ImageMagick <https://www.imagemagick.org/script/index.php>`_: for saving
212+
animated gifs;
213+
* `Pillow <https://python-pillow.org/>`_ (>=2.0): for a larger selection of
214+
image file formats: JPEG, BMP, and TIFF image files;
215+
* `LaTeX <https://miktex.org/>`_ and `GhostScript
216+
<https://ghostscript.com/download/>`_ (for rendering text with LaTeX).
218217

219218
.. note::
220219

lib/matplotlib/image.py

Lines changed: 56 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,8 @@ def _draw_list_compositing_images(
130130
has_images = any(isinstance(x, _ImageBase) for x in artists)
131131

132132
# override the renderer default if suppressComposite is not None
133-
not_composite = renderer.option_image_nocomposite()
134-
if suppress_composite is not None:
135-
not_composite = suppress_composite
133+
not_composite = (suppress_composite if suppress_composite is not None
134+
else renderer.option_image_nocomposite())
136135

137136
if not_composite or not has_images:
138137
for a in artists:
@@ -146,8 +145,7 @@ def flush_images():
146145
if len(image_group) == 1:
147146
image_group[0].draw(renderer)
148147
elif len(image_group) > 1:
149-
data, l, b = composite_images(
150-
image_group, renderer, mag)
148+
data, l, b = composite_images(image_group, renderer, mag)
151149
if data.size != 0:
152150
gc = renderer.new_gc()
153151
gc.set_clip_rectangle(parent.bbox)
@@ -182,13 +180,17 @@ def _rgb_to_rgba(A):
182180
class _ImageBase(martist.Artist, cm.ScalarMappable):
183181
zorder = 0
184182

185-
# the 3 following keys seem to be unused now, keep it for
186-
# backward compatibility just in case.
187-
_interpd = _interpd_
188-
# reverse interp dict
189-
_interpdr = {v: k for k, v in six.iteritems(_interpd_)}
190-
iterpnames = interpolations_names
191-
# <end unused keys>
183+
@cbook.deprecated("2.1")
184+
def _interpd(self):
185+
return _interpd_
186+
187+
@cbook.deprecated("2.1")
188+
def _interpdr(self):
189+
return {v: k for k, v in six.iteritems(_interpd_)}
190+
191+
@cbook.deprecated("2.1")
192+
def iterpnames(self):
193+
return interpolations_names
192194

193195
def set_cmap(self, cmap):
194196
super(_ImageBase, self).set_cmap(cmap)
@@ -349,8 +351,7 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
349351
out_height = int(ceil(out_height_base))
350352
extra_width = (out_width - out_width_base) / out_width_base
351353
extra_height = (out_height - out_height_base) / out_height_base
352-
t += Affine2D().scale(
353-
1.0 + extra_width, 1.0 + extra_height)
354+
t += Affine2D().scale(1.0 + extra_width, 1.0 + extra_height)
354355
else:
355356
out_width = int(out_width_base)
356357
out_height = int(out_height_base)
@@ -659,7 +660,7 @@ def can_composite(self):
659660

660661
def set_resample(self, v):
661662
"""
662-
Set whether or not image resampling is used
663+
Set whether or not image resampling is used.
663664
664665
ACCEPTS: True|False
665666
"""
@@ -669,7 +670,7 @@ def set_resample(self, v):
669670
self.stale = True
670671

671672
def get_resample(self):
672-
"""Return the image resample boolean"""
673+
"""Return the image resample boolean."""
673674
return self._resample
674675

675676
def set_filternorm(self, filternorm):
@@ -687,7 +688,7 @@ def set_filternorm(self, filternorm):
687688
self.stale = True
688689

689690
def get_filternorm(self):
690-
"""Return the filternorm setting"""
691+
"""Return the filternorm setting."""
691692
return self._filternorm
692693

693694
def set_filterrad(self, filterrad):
@@ -704,7 +705,7 @@ def set_filterrad(self, filterrad):
704705
self.stale = True
705706

706707
def get_filterrad(self):
707-
"""return the filterrad setting"""
708+
"""Return the filterrad setting."""
708709
return self._filterrad
709710

710711

@@ -770,13 +771,10 @@ def make_image(self, renderer, magnification=1.0, unsampled=False):
770771

771772
def _check_unsampled_image(self, renderer):
772773
"""
773-
return True if the image is better to be drawn unsampled.
774+
Return whether the image would be better drawn unsampled.
774775
"""
775-
if (self.get_interpolation() == "none" and
776-
renderer.option_scale_image()):
777-
return True
778-
779-
return False
776+
return (self.get_interpolation() == "none"
777+
and renderer.option_scale_image())
780778

781779
def set_extent(self, extent):
782780
"""
@@ -786,11 +784,8 @@ def set_extent(self, extent):
786784
to tightly fit the image, regardless of dataLim. Autoscaling
787785
state is not changed, so following this with ax.autoscale_view
788786
will redo the autoscaling in accord with dataLim.
789-
790787
"""
791-
self._extent = extent
792-
793-
xmin, xmax, ymin, ymax = extent
788+
self._extent = xmin, xmax, ymin, ymax = extent
794789
corners = (xmin, ymin), (xmax, ymax)
795790
self.axes.update_datalim(corners)
796791
self.sticky_edges.x[:] = [xmin, xmax]
@@ -821,8 +816,7 @@ def get_cursor_data(self, event):
821816
arr = self.get_array()
822817
data_extent = Bbox([[ymin, xmin], [ymax, xmax]])
823818
array_extent = Bbox([[0, 0], arr.shape[:2]])
824-
trans = BboxTransform(boxin=data_extent,
825-
boxout=array_extent)
819+
trans = BboxTransform(boxin=data_extent, boxout=array_extent)
826820
y, x = event.ydata, event.xdata
827821
i, j = trans.transform_point([y, x]).astype(int)
828822
# Clip the coordinates at array bounds
@@ -971,7 +965,6 @@ def __init__(self, ax,
971965
norm is a colors.Normalize instance to map luminance to 0-1
972966
973967
Additional kwargs are matplotlib.artist properties
974-
975968
"""
976969
super(PcolorImage, self).__init__(ax, norm=norm, cmap=cmap)
977970
self.update(kwargs)
@@ -1095,7 +1088,6 @@ def __init__(self, fig,
10951088
origin=None,
10961089
**kwargs
10971090
):
1098-
10991091
"""
11001092
cmap is a colors.Colormap instance
11011093
norm is a colors.Normalize instance to map luminance to 0-1
@@ -1148,7 +1140,6 @@ def __init__(self, bbox,
11481140
interp_at_native=True,
11491141
**kwargs
11501142
):
1151-
11521143
"""
11531144
cmap is a colors.Colormap instance
11541145
norm is a colors.Normalize instance to map luminance to 0-1
@@ -1305,30 +1296,30 @@ def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None,
13051296
13061297
The output formats available depend on the backend being used.
13071298
1308-
Arguments:
1309-
*fname*:
1310-
A string containing a path to a filename, or a Python file-like object.
1299+
Parameters
1300+
----------
1301+
fname : str or file-like
1302+
Path string to a filename, or a Python file-like object.
13111303
If *format* is *None* and *fname* is a string, the output
13121304
format is deduced from the extension of the filename.
1313-
*arr*:
1305+
arr : array-like
13141306
An MxN (luminance), MxNx3 (RGB) or MxNx4 (RGBA) array.
1315-
Keyword arguments:
1316-
*vmin*/*vmax*: [ None | scalar ]
1307+
vmin, vmax: [ None | scalar ]
13171308
*vmin* and *vmax* set the color scaling for the image by fixing the
13181309
values that map to the colormap color limits. If either *vmin*
13191310
or *vmax* is None, that limit is determined from the *arr*
13201311
min/max value.
1321-
*cmap*:
1322-
cmap is a colors.Colormap instance, e.g., cm.jet.
1323-
If None, default to the rc image.cmap value.
1324-
*format*:
1325-
One of the file extensions supported by the active
1326-
backend. Most backends support png, pdf, ps, eps and svg.
1327-
*origin*
1328-
[ 'upper' | 'lower' ] Indicates where the [0,0] index of
1329-
the array is in the upper left or lower left corner of
1330-
the axes. Defaults to the rc image.origin value.
1331-
*dpi*
1312+
cmap : matplotlib.colors.Colormap, optional
1313+
For example, ``cm.viridis``. If ``None``, defaults to the
1314+
``image.cmap`` rcParam.
1315+
format : str
1316+
One of the file extensions supported by the active backend. Most
1317+
backends support png, pdf, ps, eps and svg.
1318+
origin : [ 'upper' | 'lower' ]
1319+
Indicates where the ``(0, 0)`` index of the array is in the upper left
1320+
or lower left corner of the axes. Defaults to the ``image.origin``
1321+
rcParam.
1322+
dpi : int
13321323
The DPI to store in the metadata of the file. This does not affect the
13331324
resolution of the output image.
13341325
"""
@@ -1352,54 +1343,29 @@ def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None,
13521343

13531344

13541345
def pil_to_array(pilImage):
1346+
"""Load a PIL image and return it as a numpy array.
1347+
1348+
Grayscale images are returned as ``(M, N)`` arrays. RGB images are
1349+
returned as ``(M, N, 3)`` arrays. RGBA images are returned as ``(M, N,
1350+
4)`` arrays.
13551351
"""
1356-
Load a PIL image and return it as a numpy array. For grayscale
1357-
images, the return array is MxN. For RGB images, the return value
1358-
is MxNx3. For RGBA images the return value is MxNx4
1359-
"""
1360-
def toarray(im, dtype=np.uint8):
1361-
"""Return a 1D array of dtype."""
1362-
# Pillow wants us to use "tobytes"
1363-
if hasattr(im, 'tobytes'):
1364-
x_str = im.tobytes('raw', im.mode)
1365-
else:
1366-
x_str = im.tostring('raw', im.mode)
1367-
x = np.fromstring(x_str, dtype)
1368-
return x
1369-
1370-
if pilImage.mode in ('RGBA', 'RGBX'):
1371-
im = pilImage # no need to convert images
1372-
elif pilImage.mode == 'L':
1373-
im = pilImage # no need to luminance images
1374-
# return MxN luminance array
1375-
x = toarray(im)
1376-
x.shape = im.size[1], im.size[0]
1377-
return x
1378-
elif pilImage.mode == 'RGB':
1379-
# return MxNx3 RGB array
1380-
im = pilImage # no need to RGB images
1381-
x = toarray(im)
1382-
x.shape = im.size[1], im.size[0], 3
1383-
return x
1352+
if pilImage.mode in ['RGBA', 'RGBX', 'RGB', 'L']:
1353+
# return MxNx4 RGBA, MxNx3 RBA, or MxN luminance array
1354+
return np.asarray(pilImage)
13841355
elif pilImage.mode.startswith('I;16'):
13851356
# return MxN luminance array of uint16
1386-
im = pilImage
1387-
if im.mode.endswith('B'):
1388-
x = toarray(im, '>u2')
1357+
raw = pilImage.tobytes('raw', pilImage.mode)
1358+
if pilImage.mode.endswith('B'):
1359+
x = np.fromstring(raw, '>u2')
13891360
else:
1390-
x = toarray(im, '<u2')
1391-
x.shape = im.size[1], im.size[0]
1392-
return x.astype('=u2')
1361+
x = np.fromstring(raw, '<u2')
1362+
return x.reshape(pilImage.size[::-1]).astype('=u2')
13931363
else: # try to convert to an rgba image
13941364
try:
1395-
im = pilImage.convert('RGBA')
1365+
pilImage = pilImage.convert('RGBA')
13961366
except ValueError:
13971367
raise RuntimeError('Unknown image mode')
1398-
1399-
# return MxNx4 RGBA array
1400-
x = toarray(im)
1401-
x.shape = im.size[1], im.size[0], 4
1402-
return x
1368+
return np.asarray(pilImage) # return MxNx4 RGBA array
14031369

14041370

14051371
def thumbnail(infile, thumbfile, scale=0.1, interpolation='bilinear',

0 commit comments

Comments
 (0)
0