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

Skip to content

Commit 5b74696

Browse files
committed
Merge pull request #5718 from mdboom/image-interpolation
Rewrite of image infrastructure
2 parents 18169b2 + c9b2425 commit 5b74696

File tree

153 files changed

+13997
-12750
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

153 files changed

+13997
-12750
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Change in the ``draw_image`` backend API
2+
----------------------------------------
3+
4+
The ``draw_image`` method implemented by backends has changed its interface.
5+
6+
This change is only relevant if the backend declares that it is able
7+
to transform images by returning ``True`` from ``option_scale_image``.
8+
See the ``draw_image`` docstring for more information.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Improved image support
2+
----------------------
3+
4+
Prior to version 2.0, matplotlib resampled images by first applying
5+
the color map and then resizing the result. Since the resampling was
6+
performed on the colored image, this introduced colors in the output
7+
image that didn't actually exist in the color map. Now, images are
8+
resampled first (and entirely in floating-point, if the input image is
9+
floating-point), and then the color map is applied.
10+
11+
In order to make this important change, the image handling code was
12+
almost entirely rewritten. As a side effect, image resampling uses
13+
less memory and fewer datatype conversions than before.
14+
15+
The experimental private feature where one could "skew" an image by
16+
setting the private member ``_image_skew_coordinate`` has been
17+
removed. Instead, images will obey the transform of the axes on which
18+
they are drawn.

doc/users/whats_new/rcparams.rst

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,20 @@ Configuration (rcParams)
1919
|`svg.hashsalt` | see note |
2020
+----------------------------+--------------------------------------------------+
2121

22-
``svg.hashsalt``
23-
````````````````
22+
Added ``svg.hashsalt`` key to rcParams
23+
```````````````````````````````````````
2424

2525
If ``svg.hashsalt`` is ``None`` (which it is by default), the svg
2626
backend uses ``uuid4`` to generate the hash salt. If it is not
2727
``None``, it must be a string that is used as the hash salt instead of
2828
``uuid4``. This allows for deterministic SVG output.
29+
30+
31+
Removed the ``svg.image_noscale`` rcParam
32+
`````````````````````````````````````````
33+
34+
As a result of the extensive changes to image handling, the
35+
``svg.image_noscale`` rcParam has been removed. The same
36+
functionality may be achieved by setting ``interpolation='none'`` on
37+
individual images or globally using the ``image.interpolation``
38+
rcParam.

examples/api/demo_affine_image.py

100755100644
Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
#!/usr/bin/env python
2-
3-
41
"""
52
For the backends that supports draw_image with optional affine
63
transform (e.g., agg, ps backend), the image of the output should
@@ -24,22 +21,15 @@ def get_image():
2421
return Z
2522

2623

27-
def imshow_affine(ax, z, *kl, **kwargs):
28-
im = ax.imshow(z, *kl, **kwargs)
29-
x1, x2, y1, y2 = im.get_extent()
30-
im._image_skew_coordinate = (x2, y1)
31-
return im
32-
33-
3424
if 1:
3525

3626
# image rotation
3727

38-
fig, (ax1, ax2) = plt.subplots(1, 2)
28+
fig, ax1 = plt.subplots(1, 1)
3929
Z = get_image()
40-
im1 = imshow_affine(ax1, Z, interpolation='none',
41-
origin='lower',
42-
extent=[-2, 4, -3, 2], clip_on=True)
30+
im1 = ax1.imshow(Z, interpolation='none',
31+
origin='lower',
32+
extent=[-2, 4, -3, 2], clip_on=True)
4333

4434
trans_data2 = mtransforms.Affine2D().rotate_deg(30) + ax1.transData
4535
im1.set_transform(trans_data2)
@@ -53,13 +43,3 @@ def imshow_affine(ax, z, *kl, **kwargs):
5343

5444
ax1.set_xlim(-3, 5)
5545
ax1.set_ylim(-4, 4)
56-
57-
# image skew
58-
59-
im2 = ax2.imshow(Z, interpolation='none',
60-
origin='lower',
61-
extent=[-2, 4, -3, 2], clip_on=True)
62-
im2._image_skew_coordinate = (3, -2)
63-
64-
plt.show()
65-
#plt.savefig("demo_affine_image")

examples/images_contours_and_fields/interpolation_methods.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric',
1919
'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos']
2020

21+
np.random.seed(0)
2122
grid = np.random.rand(4, 4)
2223

2324
fig, axes = plt.subplots(3, 6, figsize=(12, 6),
@@ -26,7 +27,7 @@
2627
fig.subplots_adjust(hspace=0.3, wspace=0.05)
2728

2829
for ax, interp_method in zip(axes.flat, methods):
29-
ax.imshow(grid, interpolation=interp_method)
30+
ax.imshow(grid, interpolation=interp_method, cmap='viridis')
3031
ax.set_title(interp_method)
3132

3233
plt.show()

examples/pylab_examples/demo_annotation_box.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848

4949
arr = np.arange(100).reshape((10, 10))
5050
im = OffsetImage(arr, zoom=2)
51+
im.image.axes = ax
5152

5253
ab = AnnotationBbox(im, xy,
5354
xybox=(-50., 50.),
@@ -62,9 +63,10 @@
6263

6364
from matplotlib._png import read_png
6465
fn = get_sample_data("grace_hopper.png", asfileobj=False)
65-
arr_lena = read_png(fn)
66+
arr_img = read_png(fn)
6667

67-
imagebox = OffsetImage(arr_lena, zoom=0.2)
68+
imagebox = OffsetImage(arr_img, zoom=0.2)
69+
imagebox.image.axes = ax
6870

6971
ab = AnnotationBbox(imagebox, xy,
7072
xybox=(120., -80.),

extern/agg24-svn/include/agg_span_image_filter_gray.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ namespace agg
490490
fg_ptr = (const value_type*)base_type::source().next_y();
491491
}
492492

493-
fg >>= image_filter_shift;
493+
fg = color_type::downshift(fg, image_filter_shift);
494494
if(fg < 0) fg = 0;
495495
if(fg > color_type::full_value()) fg = color_type::full_value();
496496
span->v = (value_type)fg;

lib/matplotlib/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,7 @@ def matplotlib_fname():
847847
'savefig.extension': ('savefig.format', lambda x: x, None),
848848
'axes.color_cycle': ('axes.prop_cycle', lambda x: cycler('color', x),
849849
lambda x: [c.get('color', None) for c in x]),
850+
'svg.image_noscale': ('image.interpolation', None, None),
850851
}
851852

852853
_deprecated_ignore_map = {

lib/matplotlib/axes/_base.py

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2323,15 +2323,6 @@ def draw(self, renderer=None, inframe=False):
23232323
artists.remove(self._left_title)
23242324
artists.remove(self._right_title)
23252325

2326-
# add images to dsu if the backend supports compositing.
2327-
# otherwise, does the manual compositing without adding images to dsu.
2328-
if len(self.images) <= 1 or renderer.option_image_nocomposite():
2329-
_do_composite = False
2330-
else:
2331-
_do_composite = True
2332-
for im in self.images:
2333-
artists.remove(im)
2334-
23352326
if self.figure.canvas.is_saving():
23362327
dsu = [(a.zorder, a) for a in artists]
23372328
else:
@@ -2356,46 +2347,12 @@ def draw(self, renderer=None, inframe=False):
23562347
if self.axison and self._frameon:
23572348
self.patch.draw(renderer)
23582349

2359-
if _do_composite:
2360-
# make a composite image, blending alpha
2361-
# list of (mimage.Image, ox, oy)
2362-
2363-
zorder_images = [(im.zorder, im) for im in self.images
2364-
if im.get_visible()]
2365-
zorder_images.sort(key=lambda x: x[0])
2366-
2367-
mag = renderer.get_image_magnification()
2368-
ims = [(im.make_image(mag), 0, 0, im.get_alpha())
2369-
for z, im in zorder_images]
2370-
2371-
l, b, r, t = self.bbox.extents
2372-
width = int(mag * ((np.round(r) + 0.5) - (np.round(l) - 0.5)))
2373-
height = int(mag * ((np.round(t) + 0.5) - (np.round(b) - 0.5)))
2374-
im = mimage.from_images(height,
2375-
width,
2376-
ims)
2377-
2378-
im.is_grayscale = False
2379-
l, b, w, h = self.bbox.bounds
2380-
# composite images need special args so they will not
2381-
# respect z-order for now
2382-
2383-
gc = renderer.new_gc()
2384-
gc.set_clip_rectangle(self.bbox)
2385-
gc.set_clip_path(mtransforms.TransformedPath(
2386-
self.patch.get_path(),
2387-
self.patch.get_transform()))
2388-
2389-
renderer.draw_image(gc, round(l), round(b), im)
2390-
gc.restore()
2391-
23922350
if dsu_rasterized:
23932351
for zorder, a in dsu_rasterized:
23942352
a.draw(renderer)
23952353
renderer.stop_rasterizing()
23962354

2397-
for zorder, a in dsu:
2398-
a.draw(renderer)
2355+
mimage._draw_list_compositing_images(renderer, self, dsu)
23992356

24002357
renderer.close_group('axes')
24012358
self._cachedRenderer = renderer

lib/matplotlib/backend_bases.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ def get_image_magnification(self):
515515
"""
516516
return 1.0
517517

518-
def draw_image(self, gc, x, y, im):
518+
def draw_image(self, gc, x, y, im, trans=None):
519519
"""
520520
Draw the image instance into the current axes;
521521
@@ -531,7 +531,14 @@ def draw_image(self, gc, x, y, im):
531531
is the distance from bottom
532532
533533
*im*
534-
the :class:`matplotlib._image.Image` instance
534+
An NxMx4 array of RGBA pixels (of dtype uint8).
535+
536+
*trans*
537+
If the concrete backend is written such that
538+
`option_scale_image` returns `True`, an affine
539+
transformation may also be passed to `draw_image`. The
540+
backend should apply the transformation to the image
541+
before applying the translation of `x` and `y`.
535542
"""
536543
raise NotImplementedError
537544

0 commit comments

Comments
 (0)