thumbnailator
thumbnailator copied to clipboard
Can I set max-size instead of just size? (Only scale down)
First of all, really glad to see new Thumbnailator releases in 2020 after ~6 years of silence. Cheers!
I'd like to know if there is an option to restrict upscaling of images and only resize them down. We plan to use Thumbnailator as dynamic on-fly resizer rather than for making static thumbnails, so in rare circumstances original image may be smaller than requested size. What happens now is that image is scaled UP to requested size and becomes very messy. I haven't found any method to tell Thumbnailator not to make images larger than they already are (even if requested size says so), only make them smaller. Is there such method?
Example:
Image original size is 150*150. For some internal reasons we call resize(200, 200)
.
I want result image to stay 150*150.
void resize(InputStream is, OutputStream os, int width, int height) {
Thumbnails.of(is).size(width, height).toOutputStream(os);
}
Consider this as CSS max-width
attribute instead of width
.
I've tried a ResizerFactory
returning a NullResizer
without success, it still upscales the image.
@ILyaCyclone, unfortunately, the quick answer to your question is "no", not yet.
It's been brought up in the past as well, as issue #11.
I'll actually keep this ticket open, and supersede #11 with this ticket.
Gotcha, thanks for your attention.
This has been open for a while. Any plans to add support for this? Or at least to disable upscaling?
One solution:
public class NoScaleUpResizer implements ImageFilter {
private final int maxWidth;
private final int maxHeight;
public NoScaleUpResizer(int maxWidth, int maxHeight) {
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
}
@Override
public BufferedImage apply(BufferedImage img) {
if (img.getWidth() <= maxWidth && img.getHeight() <= maxHeight) {
return img;
}
try {
return Thumbnails.of(img).size(maxWidth, maxHeight).asBufferedImage();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
And then:
Thumbnails.of(inputFile)
.scale(1) // do not resize
.addFilter(new NoScaleUpResizer(maxWidth, maxHeight)) // then resize only if larger
.toFile(outputFile);