Hi,
I found this old thread discussing the possibility of placing un-resampled images in PS, PDF and SVG. It was questioned weather there were any potential users for such a feature to justify the effort. If it makes a difference, here is one user who very much welcome it.
I need to overlay plotting onto images without the degradation cause by resampling. Is this possible? Currently I use interpolation='nearest' and a high DPI setting for savefig, but this is not ideal.
Thanks for any help,
Geoff
Re: imshow without resampling
by Jouni K. Seppänen Apr 05, 2009; 03:13am
Eric Firing <efiring@...83...> writes:
> I'm not sure who the SVG expert is, and I presume the attached message
> applies to pdf as well as ps. I'm bringing it to your attention
> because it is suggesting what would seem to be significant
> improvements in some backends by taking better advantage of their
> native image support. I know nothing about this; would either of you
> (or anyone else) like to comment?
Thanks for forwarding this Eric - yes, it applies to pdf.
> From: Thomas Robitaille <thomas.robitaille@...83...>
> I am using matplotlib to create postscript and SVG files. I am
> currently using imshow to show the contents of an array, but this
> means that when saving vector graphics files, matplotlib resamples the
> image/array onto a finer grid. [...] Postscript and SVG (as languages)
> both allow a bitmap of an arbitrary resolution to be scaled,
> translated, and rotated without resampling.
This is complicated by the wide variety of interpolation methods offered
by imshow:
Acceptable values are *None*, 'nearest', 'bilinear',
'bicubic', 'spline16', 'spline36', 'hanning', 'hamming',
'hermite', 'kaiser', 'quadric', 'catrom', 'gaussian',
'bessel', 'mitchell', 'sinc', 'lanczos',
where None means to use the matplotlibrc value, and I think the default
is bicubic. The 'nearest' case is what you get by simply scaling the
original bitmap, so in that case all vector backends could probably
support skipping the interpolation step. The other interpolation methods
could be programmed in Postscript, but that doesn't help with other
backends - though perhaps PDF shadings (gradient fills) could be hacked
to do this. I don't know anything about SVG.
I wonder how the API between the backend and the image object should
look like. Currently the AxesImage object does essentially
im = self.make_image(renderer.get_image_magnification())
renderer.draw_image(round(l), round(b), im, self.axes.bbox.frozen(),
clippath, affine)
and then the backend does things like
h, w = im.get_size_out()
[...]
h,w,s = im.as_rgba_str()
rgba.shape = (h, w, 4)
rgb = rgba[:,:,:3]
a = rgba[:,:,3:]
Instead, I suppose AxesImage needs to first query the renderer if it
supports the interpolation being used, and if so, call a new renderer
method, say draw_interpolated_image(im). Or perhaps it could just call
the new method, and its implementation in RendererBase would fall back
to interpolating the image and calling the old draw_image. Vector
backends could override it to be smarter when possible.
A possibly related thought: the pdf backend could render some kinds of
image files by passing through the encoded image data from the original
file, so when e.g. image_demo3.py does
lena = Image.open('../data/lena.jpg')
im = imshow(lena, origin='lower')
the pdf backend could try to read the JPEG file directly, and only
decode it into a bitmap if it happens to be a wrong subtype of JPEG. For
someone who's using big image files, this would decrease both rendering
time and output size, but I don't know if there are any actual users and
if the benefit is large enough to justify the added complexity - but if
we modify the API anyway to support non-resampling imshow, it might be
good to keep that use-case in mind.
···
--
Jouni K. Seppänen
http://www.iki.fi/jks