I made this code to resize images with two factors. It works, but the quality of image is very bad after it is resized! Can you help me?
This is the code
public class ImageTest {
private static final int factor1 = 3;
private static final int factor2 = 4;
public static void main(String [] args){
JFileChooser cs = new JFileChooser();
cs.setFileSelectionMode(cs.DIRECTORIES_ONLY);
int i = cs.showOpenDialog(null);
if(i==cs.APPROVE_OPTION){
File f = cs.getSelectedFile();
File[] ff = f.listFiles();
for(int j=0;j<ff.length;j++){
String end = ff[j].getName().substring(ff[j].getName().indexOf(".")+1);
System.out.println(end);
try{
BufferedImage originalImage = ImageIO.read(ff[j]);
int type = originalImage.getType() == 0? BufferedImage.TYPE_INT_ARGB : originalImage.getType();
BufferedImage resizeImageJpg = resizeImageWithHint(originalImage, type);
ImageIO.write(resizeImageJpg, end, new File("pr/"+ff[j].getName()));
}catch(IOException e){
e.printStackTrace();
}
}
}
}
private static BufferedImage resizeImageWithHint(BufferedImage originalImage, int type){
int IMG_WIDTH = (originalImage.getWidth()*factor1)/factor2;
int IMG_HEIGHT = (originalImage.getHeight()*factor1)/factor2;
BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, type);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null);
g.dispose();
g.setComposite(AlphaComposite.Src);
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);
return resizedImage;
}
}
I saw on web that resizeImageWithHint is done within the scope so as not to lose quality.. but it does! why? can you help me with this?
The best article I have ever read on this topic is The Perils of Image.getScaledInstance() (web archive).
In short: You need to use several resizing steps in order to get a good image. Helper method from the article:
public BufferedImage getScaledInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint,
boolean higherQuality)
{
int type = (img.getTransparency() == Transparency.OPAQUE) ?
BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage)img;
int w, h;
if (higherQuality) {
// Use multi-step technique: start with original size, then
// scale down in multiple passes with drawImage()
// until the target size is reached
w = img.getWidth();
h = img.getHeight();
} else {
// Use one-step technique: scale directly from original
// size to target size with a single drawImage() call
w = targetWidth;
h = targetHeight;
}
do {
if (higherQuality && w > targetWidth) {
w /= 2;
if (w < targetWidth) {
w = targetWidth;
}
}
if (higherQuality && h > targetHeight) {
h /= 2;
if (h < targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
} while (w != targetWidth || h != targetHeight);
return ret;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With