imshow without resampling in the ps backend.

Jae-Joon Lee <lee.j.joon@...149...> writes:

While extending this to other backend such as pdf and svg should be
straight forward, I want to hear how others think about the overall
approach, e.g., api change and such. The current approach is to
minimize change in backends.

While the backend API is being changed, would it be similarly easy to
support arbitrary affine transformations? It would make the API more
symmetric, since many other draw_* methods take an affine
transformation, and I guess at least the PS and PDF backends could
easily support this.

* If there are multiple images (and the ps backend is used), the
images are resampled as they are compositted into a single image.

The Figure.draw method already has some logic for not compositing
multiple images:

        if len(self.images)<=1 or not_composite or \
                not allequal([im.origin for im in self.images]):

I suppose this could also include a check for whether all images have
the same transformation. Anyway, I'm not quite sure what the win from
compositing is for a vector backend.

* The current solution forces not to resample whenever
interpolation=="nearest", I think this is generally good behavior.
However, on the highly extreme case of very high resolution of image
(e.g., image dpi > 1000 ?), it might be better if the image is
resampled (i.e., downsampled).

This sounds like it would make sense for naive users but could get very
annoying for somebody who really does want high resolution (e.g. for
zooming in in a viewer application).

···

--
Jouni K. Seppänen
http://www.iki.fi/jks

Jae-Joon Lee <lee.j.joon@...149...> writes:

While extending this to other backend such as pdf and svg should be
straight forward, I want to hear how others think about the overall
approach, e.g., api change and such. The current approach is to
minimize change in backends.

While the backend API is being changed, would it be similarly easy to
support arbitrary affine transformations? It would make the API more
symmetric, since many other draw_* methods take an affine
transformation, and I guess at least the PS and PDF backends could
easily support this.

Yes, supporting arbitrary affine transform would not be difficult. On
the other hand, I'm not sure if that feature is practically useful,
assuming that other rasterizing backend won't implement it. I'll think
about it.

* If there are multiple images (and the ps backend is used), the
images are resampled as they are compositted into a single image.

The Figure.draw method already has some logic for not compositing
multiple images:

   if len\(self\.images\)&lt;=1 or not\_composite or \\
           not allequal\(\[im\.origin for im in self\.images\]\):

I suppose this could also include a check for whether all images have
the same transformation. Anyway, I'm not quite sure what the win from
compositing is for a vector backend.

One benefit of compositing would be an indirect support of alpha
compositing in the ps backend, although it is not clear this is
practically useful. Checking whether compositing is required seems not
very straight forward to me. We may try to sort out images that needs
to be composited and those does not. Anyhow, I am personally happy
with the current behavior so I may leave it as is, and let others take
it if they want.

* The current solution forces not to resample whenever
interpolation=="nearest", I think this is generally good behavior.
However, on the highly extreme case of very high resolution of image
(e.g., image dpi > 1000 ?), it might be better if the image is
resampled (i.e., downsampled).

This sounds like it would make sense for naive users but could get very
annoying for somebody who really does want high resolution (e.g. for
zooming in in a viewer application).

What I meant was the case when the dpi of the image painted on the
canvas is much higher than the dpi of the canvas itself (I mean the
dpi of the typical postscript output device). Anyhow, I guess the
current behavior is good enough, and it seems more reasonable to let
users do the down-sampling explicitly if they want.

Regards,

-JJ

···

On Wed, Dec 16, 2009 at 12:59 PM, Jouni K. Seppänen <jks@...278...> wrote:

--
Jouni K. Seppänen
http://www.iki.fi/jks

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Jae-Joon Lee wrote:

  

While the backend API is being changed, would it be similarly easy to
support arbitrary affine transformations? It would make the API more
symmetric, since many other draw_* methods take an affine
transformation, and I guess at least the PS and PDF backends could
easily support this.

Yes, supporting arbitrary affine transform would not be difficult. On
the other hand, I'm not sure if that feature is practically useful,
assuming that other rasterizing backend won't implement it. I'll think
about it.

I second the notion that affine transformations on images would be useful. There are a lot of things one can do with this, such as make pseudo-perspective projections of texture-mapped rectangles. This is exactly one of the things that I routinely do in Inkscape.

I'm reasonably sure Cairo supports arbitrary affine transformations when drawing image data -- I don't know about Agg.

-Andrew

···

On Wed, Dec 16, 2009 at 12:59 PM, Jouni K. Seppänen <jks@...278...> wrote:

I change the api to support an arbitrary affine transform. The current api is

def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None):

dx, dy is the width and height of the image, i.e.,
The 4 edge points of the image will be
(x, y), (x+dx, y), (x+dx, y+dy), (x, y+dy) after transformed by *transform*.
And if transform involves rotation or skew, the image should also be
rotated and skewed.

Attached is a small example to utilized this functionality.
Note that it only works with the ps-backend.

I personally don't have much use case for rotated or skewed images.
So, it would be great if others can suggest some user-space api.

What I have in my mind is to extend the "extent" keyword of the imshow
and make it optionally take a tuple of 6 numbers, which are (x1,
x_lrc, x2, y1, y_lrc, y2).
x1, x2, y1, y2 are same as the original "extent", and the (x_lrc,
y_lrc) represent the coordinate of the lower-right corner of the
image.

So, the imshow in the attached example will become somthing like

im = plt.imshow(Z, interpolation='nearest', cmap=cm.jet,
                origin='lower', extent=[-2, 3, 4, -3, -2, 2])

And, the transformation will be calculated internally by the Image class.

Any thought?

-JJ

image_skew_demo.py (1.52 KB)

···

On Wed, Dec 16, 2009 at 3:41 PM, Andrew Straw <strawman@...36...> wrote:

Jae-Joon Lee wrote:

On Wed, Dec 16, 2009 at 12:59 PM, Jouni K. Seppänen <jks@...278...> wrote:

While the backend API is being changed, would it be similarly easy to
support arbitrary affine transformations? It would make the API more
symmetric, since many other draw_* methods take an affine
transformation, and I guess at least the PS and PDF backends could
easily support this.

Yes, supporting arbitrary affine transform would not be difficult. On
the other hand, I'm not sure if that feature is practically useful,
assuming that other rasterizing backend won't implement it. I'll think
about it.

I second the notion that affine transformations on images would be useful.
There are a lot of things one can do with this, such as make
pseudo-perspective projections of texture-mapped rectangles. This is exactly
one of the things that I routinely do in Inkscape.

I'm reasonably sure Cairo supports arbitrary affine transformations when
drawing image data -- I don't know about Agg.

-Andrew

Jae-Joon Lee wrote:

What I have in my mind is to extend the "extent" keyword of the imshow
and make it optionally take a tuple of 6 numbers, which are (x1,
x_lrc, x2, y1, y_lrc, y2).
x1, x2, y1, y2 are same as the original "extent", and the (x_lrc,
y_lrc) represent the coordinate of the lower-right corner of the
image.
  

It's not clear to me if this proposal lets one specify any arbitrary affine transformation. Does it?

Any thought?
  

In general -- very nice. Thanks.

In specific, I think the way you have already implemented things is sufficient. I think if a user can write a little helper function (as in your demo) to avoid a dumbed-down API being part of MPL, that would be best. Anyone specifying their own affine transform is probably going to want a pretty precise level of control, anyway. (Of course if your extent keyword proposal is already a general purpose API, then please ignore this comment.)

-Andrew

It's not clear to me if this proposal lets one specify any arbitrary affine
transformation. Does it?

I believe it does. 3 coordinates will define 6 equations where we have
6 unknowns of the affine matrix.
The question is how user want to specify the transform.
The extended extent keyword would be useful for the cases like the
pseudo-perspective projection that you mentioned. But, it will not be
very convenient for the cases like simple rotation.

In general -- very nice. Thanks.

In specific, I think the way you have already implemented things is
sufficient. I think if a user can write a little helper function (as in your
demo) to avoid a dumbed-down API being part of MPL, that would be best.
Anyone specifying their own affine transform is probably going to want a
pretty precise level of control, anyway. (Of course if your extent keyword
proposal is already a general purpose API, then please ignore this comment.)

I, personally, don't like the idea that user needs to define his/her
own transform to rotate/skew the image. Rotation and skew seems more
like properties of the image, rather than the transform.

Anyhow, unless others step in, I may leave it as is (partially because
I don't have much use case for rotated/skewed images for now). And, I
hope someone implement similar affine transform for other backends.
For the backends that requires resampling (agg, etc.), it might be
better if the affine transform is taken care during the resampling
(i.e., in the Image.draw method) rather than to be delegated to the
backends.

Regards,

-JJ

···

On Thu, Dec 17, 2009 at 5:03 PM, Andrew Straw <strawman@...36...> wrote:

-Andrew

Agg backends (in addition to the ps backend) now support
affine-transformed image.
Regards,

-JJ

image.png

···

On Thu, Dec 17, 2009 at 7:05 PM, Jae-Joon Lee <lee.j.joon@...149...> wrote:

On Thu, Dec 17, 2009 at 5:03 PM, Andrew Straw <strawman@...36...> wrote:

It's not clear to me if this proposal lets one specify any arbitrary affine
transformation. Does it?

I believe it does. 3 coordinates will define 6 equations where we have
6 unknowns of the affine matrix.
The question is how user want to specify the transform.
The extended extent keyword would be useful for the cases like the
pseudo-perspective projection that you mentioned. But, it will not be
very convenient for the cases like simple rotation.

In general -- very nice. Thanks.

In specific, I think the way you have already implemented things is
sufficient. I think if a user can write a little helper function (as in your
demo) to avoid a dumbed-down API being part of MPL, that would be best.
Anyone specifying their own affine transform is probably going to want a
pretty precise level of control, anyway. (Of course if your extent keyword
proposal is already a general purpose API, then please ignore this comment.)

I, personally, don't like the idea that user needs to define his/her
own transform to rotate/skew the image. Rotation and skew seems more
like properties of the image, rather than the transform.

Anyhow, unless others step in, I may leave it as is (partially because
I don't have much use case for rotated/skewed images for now). And, I
hope someone implement similar affine transform for other backends.
For the backends that requires resampling (agg, etc.), it might be
better if the affine transform is taken care during the resampling
(i.e., in the Image.draw method) rather than to be delegated to the
backends.

Regards,

-JJ

-Andrew