coobird / thumbnailator

Thumbnailator - a thumbnail generation library for Java
MIT License
5.14k stars 784 forks source link

How do I position a scaled image while maintaining the aspect ratio? #154

Closed osbald closed 11 months ago

osbald commented 4 years ago

This is similar request to issue #24 but the solution there doesn't produce the result I'm after.

I'd like a thumbnail of a fixed size lets say 200x,200. Currently if I use size(200,200) and the source image isn't exactly square I can get a 200x150 thumbnail back due to the aspect ratio corrected fit.

What I'm after is the means to get that 200x200 image back, but with the smaller 200x150 correct ratio image positioned inside it - most often I'd expect at the center. So not forceSize() and not crop().

Something a bit like:

Thumbnails.of(src).outputSize(200,200).keepAspectRatio(true).position(Positions.CENTER).asBufferedImage();

Where outputSize() above also drives size() implicitly.

This does create one big problem as what to fill any additional empty space in the final image with. For PNG transparent is an obvious choice, but that won't work for JPGs. It'd probally have to be specified by the user, but tricky to automate/detect the best background choice to suit all images.

coobird commented 4 years ago

What you're trying to accomplish is not exposed directly through the Thumbnails API, but it's possible through using the Canvas filter. (Which happens to be the filter used to implement crop.)

Thumbnails.of(sourceImg)
        .size(200, 200)
        .addFilter(new Canvas(200, 200, Positions.CENTER, false, Color.WHITE))
        .asBufferedImage();

As long as the dimensions in size and the Canvas constructors are the same, the result is an image that's always 200 x 200 with the thumbnail placed inside of it. The color can be changed in the argument of the constructor.

This is not really intuitive, so there probably should be an API for it..

Let me know if this works for you.

coobird commented 11 months ago

Question answered. Closing for no follow-up activity.