The modern web applications have been swift-ed to address very good user interface. Images are the very important entities in order to improve user interface. So, as a programmer - we should be ready to manipulate images if needed i.e.; probably we might have to re-size user uploaded images or we might have to create thumbnails for images etc.

There are lot of APIs are available to convert/manipulate images. But I had to develop my own program because our server runs only on JDK 1.4 and we don't have any plans to upgrade it to 1.5 version.

Hope you understand! just to be clear - we need to create develop a program to create image thumbnail or resize image with a decent quality through Java 1.4 version.

I've tried with several logics to create a very good quality image re-size through Java program. Nothing works initially, but at the last I came to a conclusion that I've got decent quality through the below logic. I'm trying an other logic also, which makes it more effective, but that is still in testing mode. It has been tested with Java 1.4, 1.5 versions.

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import javax.imageio.ImageIO;
import java.io.IOException;

/**
* This class will be helpful when you want to resize an image with decent quality.
* @author SANTHOSH REDDY MANDADI
* @since 20-April-2009
* @version 2.0.7
*/
public class PerfectImageResizer
{
public static void createThumbnail(String sourceFile, String destFile,
int targetWidth,int targetHeight) throws Exception
{
try
{
BufferedImage img = ImageIO.read(new File(sourceFile));
int iw = img.getWidth();
int ih = img.getHeight();

Object hint = RenderingHints.VALUE_INTERPOLATION_BILINEAR;
int type = img.getType() == 0? BufferedImage.TYPE_INT_ARGB : img.getType();

// First get down to no more than 2x in W & H
while (iw > targetWidth*2 || ih > targetHeight*2) {
iw = (iw > targetWidth*2) ? iw/2 : iw;
ih = (ih > targetHeight*2) ? ih/2 : ih;
img = scaleImage(img, type, hint, iw, ih);
}

// REMIND: Conservative approach:
// first get W right, then worry about H

// If still too wide - do a horizontal trilinear blend
// of img and a half-width img
if (iw > targetWidth) {
int iw2 = iw/2;
BufferedImage img2 = scaleImage(img, type, hint, iw2, ih);
if (iw2 < targetWidth) {
img = scaleImage(img, type, hint, targetWidth, ih);
img2 = scaleImage(img2, type, hint, targetWidth, ih);
interp(img2, img, iw-targetWidth, targetWidth-iw2);
}
img = img2;
iw = targetWidth;
}
// iw should now be targetWidth or smaller

// If still too tall - do a vertical trilinear blend
// of img and a half-height img
if (ih > targetHeight) {
int ih2 = ih/2;
BufferedImage img2 = scaleImage(img, type, hint, iw, ih2);
if (ih2 < targetHeight) {
img = scaleImage(img, type, hint, iw, targetHeight);
img2 = scaleImage(img2, type, hint, iw, targetHeight);
interp(img2, img, ih-targetHeight, targetHeight-ih2);
}
img = img2;
ih = targetHeight;
}
// ih should now be targetHeight or smaller

// If we are too small, then it was probably because one of
// the dimensions was too small from the start.
if (iw < targetWidth && ih < targetHeight) {
img = scaleImage(img, type, hint, targetWidth, targetHeight);
}
ImageIO.write(img, destFile.substring(destFile.lastIndexOf('.')+1), new FileOutputStream(destFile));

} catch (IOException thumbException)
{
thumbException.printStackTrace();
throw new Exception(thumbException);
}
}
private static BufferedImage scaleImage(BufferedImage orig,int type,Object hint,int w, int h)
{
BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(orig, 0, 0, w, h, null);
g2.dispose();
return tmp;
}

private static void interp(BufferedImage img1,BufferedImage img2,int weight1,int weight2)
{
float alpha = weight1;
alpha /= (weight1 + weight2);
Graphics2D g2 = img1.createGraphics();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
g2.drawImage(img2, 0, 0, null);
g2.dispose();
}
public static void main(String[] args) throws Exception
{
String sourceFile="acu-final.jpg";
BufferedImage img = ImageIO.read(new File(sourceFile));
int iw = img.getWidth();
int ih = img.getHeight();
int targetWidth=74;
double imgHeightPercentage=((double)targetWidth/(double)iw)*100;
double imgTotalHeight=ih * (imgHeightPercentage/100);
int targetHeight=(int)Math.round(imgTotalHeight);
PerfectImageResizer.createThumbnail(sourceFile,"acu-finalt.jpg",targetWidth,targetHeight);
}
}

Replace your source file name, destination file name in the main block and run it. I'm sure you'll get a decent quality.

Note: If you would like to resize the horizontal and vertical as proportionately, you need to pass the values exactly. Here is the logic to give the proportionate values.

imgWidth = image.getWidth(null);
imgHeight = image.getHeight(null);
int newWidth=100; //Hard code the width you want
d
ouble imgHeightPercentage= (newWidth/(double)imgWidth)*100;
double imgTotalHeight=imgHeight*(imgHeightPercentage/100);
int newHeight=(int)Math.round(imgTotalHeight);

Pass newWidth and newHeight as the parameters to the above method createThumbnail method.

Another image resize technique, which gives the best quality

If you've sometime, why don't you checkout my other Java programs.