Can someone please help with some code for creating a thumbnail for a JPEG in Java.
I'm new at this, so a step by step explanation would be appreciated.
Can someone please help with some code for creating a thumbnail for a JPEG in Java.
I'm new at this, so a step by step explanation would be appreciated.
Image img = ImageIO.read(new File("test.jpg")).getScaledInstance(100, 100, BufferedImage.SCALE_SMOOTH);
This will create a 100x100 pixels thumbnail as an Image object. If you want to write it back to disk simply convert the code to this:
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
img.createGraphics().drawImage(ImageIO.read(new File("test.jpg")).getScaledInstance(100, 100, Image.SCALE_SMOOTH),0,0,null);
ImageIO.write(img, "jpg", new File("test_thumb.jpg"));
Also if you are concerned about speed issues (the method described above is rather slow if you want to scale many images) use these methods and the following declaration :
private BufferedImage scale(BufferedImage source,double ratio) {
int w = (int) (source.getWidth() * ratio);
int h = (int) (source.getHeight() * ratio);
BufferedImage bi = getCompatibleImage(w, h);
Graphics2D g2d = bi.createGraphics();
double xScale = (double) w / source.getWidth();
double yScale = (double) h / source.getHeight();
AffineTransform at = AffineTransform.getScaleInstance(xScale,yScale);
g2d.drawRenderedImage(source, at);
g2d.dispose();
return bi;
}
private BufferedImage getCompatibleImage(int w, int h) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
BufferedImage image = gc.createCompatibleImage(w, h);
return image;
}
And then call :
BufferedImage scaled = scale(img,0.5);
where 0.5 is the scale ratio and img is a BufferedImage containing the normal-sized image.
This is simple way of creating a 100 X 100 thumbnail without any stretch or skew in image.
private void saveScaledImage(String filePath,String outputFile){
try {
BufferedImage sourceImage = ImageIO.read(new File(filePath));
int width = sourceImage.getWidth();
int height = sourceImage.getHeight();
if(width>height){
float extraSize= height-100;
float percentHight = (extraSize/height)*100;
float percentWidth = width - ((width/100)*percentHight);
BufferedImage img = new BufferedImage((int)percentWidth, 100, BufferedImage.TYPE_INT_RGB);
Image scaledImage = sourceImage.getScaledInstance((int)percentWidth, 100, Image.SCALE_SMOOTH);
img.createGraphics().drawImage(scaledImage, 0, 0, null);
BufferedImage img2 = new BufferedImage(100, 100 ,BufferedImage.TYPE_INT_RGB);
img2 = img.getSubimage((int)((percentWidth-100)/2), 0, 100, 100);
ImageIO.write(img2, "jpg", new File(outputFile));
}else{
float extraSize= width-100;
float percentWidth = (extraSize/width)*100;
float percentHight = height - ((height/100)*percentWidth);
BufferedImage img = new BufferedImage(100, (int)percentHight, BufferedImage.TYPE_INT_RGB);
Image scaledImage = sourceImage.getScaledInstance(100,(int)percentHight, Image.SCALE_SMOOTH);
img.createGraphics().drawImage(scaledImage, 0, 0, null);
BufferedImage img2 = new BufferedImage(100, 100 ,BufferedImage.TYPE_INT_RGB);
img2 = img.getSubimage(0, (int)((percentHight-100)/2), 100, 100);
ImageIO.write(img2, "jpg", new File(outputFile));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Maybe the simplest approach would be:
static public BufferedImage scaleImage(BufferedImage image, int max_width, int max_height) {
int img_width = image.getWidth();
int img_height = image.getHeight();
float horizontal_ratio = 1;
float vertical_ratio = 1;
if(img_height > max_height) {
vertical_ratio = (float)max_height / (float)img_height;
}
if(img_width > max_width) {
horizontal_ratio = (float)max_width / (float)img_width;
}
float scale_ratio = 1;
if (vertical_ratio < horizontal_ratio) {
scale_ratio = vertical_ratio;
}
else if (horizontal_ratio < vertical_ratio) {
scale_ratio = horizontal_ratio;
}
int dest_width = (int) (img_width * scale_ratio);
int dest_height = (int) (img_height * scale_ratio);
BufferedImage scaled = new BufferedImage(dest_width, dest_height, image.getType());
Graphics graphics = scaled.getGraphics();
graphics.drawImage(image, 0, 0, dest_width, dest_height, null);
graphics.dispose();
return scaled;
}
Solution for the case when you want to create a quadrate (75x75) thumbnail from the non-quadrate source.
Code below first crop original image to quadrate using smaller size than resizes the quadrate image.
public static void generateThumbnailWithCrop(String imgPath, String thumbnailPath, int size) throws IOException {
BufferedImage sourceImage = ImageIO.read(new File(imgPath));
int width = sourceImage.getWidth();
int height = sourceImage.getHeight();
int smallerSize = width > height ? height : width;
BufferedImage quadrateImage = cropToQuadrate(sourceImage, smallerSize);
int type = quadrateImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : quadrateImage.getType();
BufferedImage resizedImage = resizeImageWithHint(quadrateImage, type, size, size);
File thumb = new File(thumbnailPath);
thumb.getParentFile().mkdirs();
ImageIO.write(resizedImage, "jpg", thumb);
}
private static BufferedImage cropToQuadrate(BufferedImage sourceImage, int size) {
BufferedImage img = sourceImage.getSubimage(0, 0, size, size);
BufferedImage copyOfImage = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = copyOfImage.createGraphics();
g.drawImage(img, 0, 0, null);
return copyOfImage;
}
private static BufferedImage resizeImageWithHint(BufferedImage originalImage, int type, int width, int height) {
BufferedImage resizedImage = new BufferedImage(width, height, type);
Graphics2D g = resizedImage.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setComposite(AlphaComposite.Src);
g.drawImage(originalImage, 0, 0, width, height, null);
g.dispose();
return resizedImage;
}
Thumbnails4j (I'm a maintainer, but it's owned by Elastic) is a java library that can be used to create thumbnails from image files, as well as from other file types.
File input = new File("/path/to/my_file.jpeg");
Thumbnailer thumbnailer = new ImageThumbnailer("png"); // or "jpg", whichever output format you want
List<Dimensions> outputDimensions = Collections.singletonList(new Dimensions(100, 100));
BufferedImage output = thumbnailer.getThumbnails(input, outputDimensions).get(0);