SFML community forums

General => Feature requests => Topic started by: nihohit on April 10, 2012, 11:10:52 am

Title: Image rotation
Post by: nihohit on April 10, 2012, 11:10:52 am
as described here (http://en.sfml-dev.org/forums/index.php?topic=7550.0), I think that there should be at least the three common rotations available to Image, to enable complex Images. Don't know if this is relevant, but I know that in System.Drawing Image has these options.

BTW, I'm a bit question-heavy at the moment, but thanks for the awesome help and quick replies. SFML really eased my learning to code games, and the help here is really great.
Title: Re: Image rotation
Post by: Laurent on April 10, 2012, 11:28:49 am
This is something that can be considered for future minor releases of SFML 2.
Title: Re: Image rotation
Post by: JayArby on April 10, 2012, 05:42:31 pm
Couldn't you rotate a sprite and render it to an image?
Title: Re: Image rotation
Post by: Laurent on April 10, 2012, 07:23:06 pm
Couldn't you rotate a sprite and render it to an image?
This would be overkill, and too complicated for users.
Basically, since rotating sprites is free, there's almost no need to pre-rotate images. But there are use cases where it is necessary, for example when you compose more complex images.
Title: Re: Image rotation
Post by: RokB on August 06, 2015, 09:10:57 am
Would this still be considered? This would indeed be very useful when creating complex images.
Title: Re: Image rotation
Post by: Nexus on August 06, 2015, 09:26:02 am
When rotation is provided, vertical/horizontal mirroring should be provided, too.

But is it something that needs to be done within SFML? When the implementation copies the entire image, the user could as well do that himself... Such operations would mainly be interesting when they transform indices rather than actually rewriting the image.
Title: Re: Image rotation
Post by: RokB on August 06, 2015, 09:59:54 am
I believe vertical/horizontal mirroring is already provided, which is why I thought it was odd that rotation isn't.
Title: Re: Image rotation
Post by: Hapax on August 06, 2015, 12:31:39 pm
Rotation is a more complicated than flipping. Even 90° is still a little more complicated than flipping.

That said, since flipping is already included, you'd think that both 90° rotations would be too. (180° could be included too since it would be more efficient than having to do both flips)

I'm not sure if the original suggestion was for arbitrary angles though but I think that's far too high for SFML.
Title: Re: Image rotation
Post by: Nexus on August 06, 2015, 12:58:36 pm
As mentioned, an interesting optimization are lazy indices. Whether such an optimization makes sense depends on the use cases, e.g. how often people use getPixel() and setPixel() to access single pixels.

Depending on the transform, an internal proxy transforms the index pair before actual array access. For example:
They can of course be chained. When a function needs direct access to the underlying array, the latter is rewritten.
Title: Re: Image rotation
Post by: Hapax on August 06, 2015, 01:10:48 pm
So, the pixel co-ordinate would be transformed internally when getting and setting the pixel?
That sounds like a good idea, as long as the direct pixel access is not covered and removed.
One scenario to consider is if that image is not square and it's rotated 90°:

Also, do we assume that the image is rotated and then 'moved' to fit into the top-left co-ordinate (0, 0) after rotation?
Title: Re: Image rotation
Post by: eXpl0it3r on August 06, 2015, 01:34:18 pm
As mentioned, an interesting optimization are lazy indices.
Do you mean optimization or did you just use that word?
Because lazy indices are not optimized at all, due to high cache misses. ;)
Title: Re: Image rotation
Post by: Nexus on August 06, 2015, 02:06:35 pm
which colour is returned from the getter when outside of the actual image?
Access outside bounds will be undefined behavior,  like before.

Also, do we assume that the image is rotated and then 'moved' to fit into the top-left co-ordinate (0, 0) after rotation?
If the image rotates, its dimensions will change, there's no need to fit/align/move something.

Do you mean optimization or did you just use that word?
The optimization would obviously be the copies we can avoid as long as we don't need them. Imagine that a user wants to rotate by 90° and then flip horizontally. Without lazy evaluation, there are two copies required, with lazy evaluation at most one -- possibly none.

Because lazy indices are not optimized at all, due to high cache misses.
Good point. However I'm not sure if setPixel/getPixel is mainly used in iteration; it's a random access interface. And even now, you can easily have bad cache access patterns, because as a user you don't know whether you should iterate row-major or column-major.

If iteration proves to be an often-needed feature, it would still be possible to provide a dedicated iterator interface, which would walk efficiently in memory. But don't forget that it's always possible to "evaluate" the image and rewrite it in memory, so that the index transform becomes again the identity.

Maybe we should ask ourselves, how sf::Image is usually used... I think it's:
1. as a container to convert between different image classes
2. to perform "global" pixel operations, like color-mask, pre-alpha multiplying, flip, rotate
3. to set single pixels, e.g. for UI or tileset composition
Title: Re: Image rotation
Post by: RokB on August 06, 2015, 02:13:59 pm
There wouldn't have to be copies of the image when rotating. The image can be rotated by rearranging the pixels.
Title: Re: Image rotation
Post by: Hapax on August 06, 2015, 02:17:42 pm
If the image rotates, its dimensions will change, there's no need to fit/align/move something.
Ah, I see. I was thinking that the image would be the same size and the pixels would be rotated inside them, rather than (apparently) rotating the image object itself.
However, the dimensions themselves wouldn't change as the image isn't actually being rotated. The retrieved image size would just be the size transformed by the rotation.

RokB, re-arranging the pixels is computationally expensive. Transforming the getPixel() and setPixel() co-ordinates would be comparatively much faster. One problem with that approach is when you create a texture from that image. It looks like it would have to do the pixel re-arranging before/during that conversion.
Title: Re: Image rotation
Post by: eXpl0it3r on August 06, 2015, 02:19:27 pm
Maybe we should ask ourselves, how sf::Image is usually used... I think it's:
1. as a container to convert between different image classes
2. to perform "global" pixel operations, like color-mask, pre-alpha multiplying, flip, rotate
3. to set single pixels, e.g. for UI or tileset composition
Yeah, as with most feature requests, I'm missing a few use case scenarios.

And I'm fully satisfied with:
But there are use cases where it is necessary, for example when you compose more complex images.
Title: Re: Image rotation
Post by: RokB on August 06, 2015, 02:32:18 pm
RokB, re-arranging the pixels is computationally expensive. Transforming the getPixel() and setPixel() co-ordinates would be comparatively much faster. One problem with that approach is when you create a texture from that image. It looks like it would have to do the pixel re-arranging before/during that conversion.

Another problem would arise when using Image::copy() it seems, which is necessary for creating complex images. Personally, I think it would be a lot simpler to create a function rearranging the image rather than to go around tweaking everything that currently uses the class. I've already done so for my own use. It's not insanely expensive and it's not like it's the sort of thing you'd be using very often.
Title: Re: Image rotation
Post by: Nexus on August 06, 2015, 02:50:07 pm
Personally, I think it would be a lot simpler to create a function rearranging the image rather than to go around tweaking everything that currently uses the class.
Nothing will break of course, it's just an internal optimization.

For simplicity, we can mark copy() and other operations so that they "evaluate" the image. Lazy evaluation loses a bit of its usefulness as such, with a bit of thought also this could be addressed.

One advantage that lazy evaluation definitely has is that it allows two subsequent transforms to be executed efficiently (O(1)). For example, it would then be enough to provide rotateCcw() and rotateCw() -- we wouldn't need a rotate180(), because twice 90° costs nothing.
Title: Re: Image rotation
Post by: Hapax on August 07, 2015, 03:54:36 pm
we wouldn't need a rotate180(), because twice 90° costs nothing.
This is true and I'm sure it'd be perfectly acceptable. The only reason I mentioned a separate 180 degree rotation previously was because it can be optimised to be faster than 90.