a. Saving original textures / images to image files of different size
Is probably the largest use case.
I might say have a screenshot of the screen I want to scale down to a different size upon saving.
Or I might be using the image as a canvas for drawing and may want to resize the canvas at some point.
Two approaches are:
1) draw to a render texture, then converting that texture to an image and saving that (as you already touched on but seems simple enough; it uses OpenGL to do the work),
2) resize the pixel data within an image
The second is image manipulation and seems "out-of-scope" for SFML, especially as it can be done manually or requires specific approaches.
b. Loading original textures / image to textures of different size
It's usually better to resize the images before saving to the file and then you can just use the image as is.
Of course, if you need a scaleable image, as you mentioned, too many different image files might be needed.
For example I might have a button with different images for untouched, touched, clicked.
I'd want to keep each image at the same display size when rendering,
but rather than calculating how much scaling would be needed each user interaction,
it would just make calculations easier if I could resize and cache the images on load,
and then use uniform scale factors for all states.
This is a bit of a strange example.
To fit an image (or part of an image) in a specified rectangular area, use an sf::Rectangle, set its position and size, then set its texture rectangle to cover the part of the texture needed. No scaling necessary.
Since "simple" is the thing you focus on the most, I presume you find it the most important.
So, here's a simple example of how to resize an image:
void resizeImage(const sf::Image& originalImage, sf::Image& resizedImage)
{
const sf::Vector2u originalImageSize{ originalImage.getSize() };
const sf::Vector2u resizedImageSize{ resizedImage.getSize() };
for (unsigned int y{ 0u }; y < resizedImageSize.y; ++y)
{
for (unsigned int x{ 0u }; x < resizedImageSize.x; ++x)
{
unsigned int origX{ static_cast<unsigned int>(static_cast<double>(x) / resizedImageSize.x * originalImageSize.x) };
unsigned int origY{ static_cast<unsigned int>(static_cast<double>(y) / resizedImageSize.y * originalImageSize.y) };
resizedImage.setPixel(x, y, originalImage.getPixel(origX, origY));
}
}
}
This fills the second image (at its current size) with the first image, stretched or squashed to fit the second. So, you can just create (or re-create) the second image to whatever size you need before using the function.
EDIT: added simple image resizing example